- Knowledge Base
- Amazon Web Services
- Amazon CloudFront
- FieldLevel Encryption
Ensure that field-level encryption is enabled for your Amazon CloudFront distributions in order to help protect sensitive data such as credit card numbers or social security numbers, and to help protect your data across application services.
This rule can help you with the following compliance standards:
- PCI
- HIPAA
- GDPR
- APRA
- NIST4
For further details on compliance standards supported by Conformity, see here.
This rule can help you work with the AWS Well-Architected Framework.
This rule resolution is part of the Conformity Security & Compliance tool for AWS.
With Amazon CloudFront field-level encryption, you add an additional layer of security, along with SSL encryption (HTTPS), that lets you protect specific sensitive data throughout system processing so that only certain applications within your environment can see this data.
Audit
To determine if your Amazon CloudFront distributions are using field-level encryption, perform the following operations:
Using AWS Console
01 Sign in to the AWS Management Console.
02 Navigate to Amazon CloudFront console at https://console.aws.amazon.com/cloudfront/v3/.
03 In the left navigation panel, under CloudFront, choose Distributions.
04 Click on the name (link) of the Amazon CloudFront distribution that you want to examine.
05 Select the Behaviors tab to access the cache behavior(s) configured for the selected distribution.
06 Select the cache behavior that you want to examine and choose Edit.
07 On the Edit behaviorconfiguration page, choose Additional settings, and check the Field-level encryption setting for any active field-level encryption configurations. If the Field-level encryption setting does not have any active field-level encryption configurations, the selected cache behavior is not configured to use field-level encryption to protect private content.
08 Repeat steps no. 6 and 7 to determine the setting status for each cache behavior associated with the selected distribution. If the Field-level encryption setting is not enabled for the associated cache behavior(s), the selected Amazon CloudFront distribution is not configured to encrypt private or sensitive data at the edge locations.
09 Repeat steps no. 4 – 8 for each CloudFront distribution available within your AWS cloud account.
Using AWS CLI
01 Run list-distributions command (OSX/Linux/UNIX) with custom query filters to list the ID of each Amazon CloudFront distribution created in your AWS account:
aws cloudfront list-distributions --output table --query 'DistributionList.Items[*].Id'
02 The command output should return a table with the requested distribution ID(s):
-------------------- |ListDistributions | +------------------+ | ABCDABCDABCDAB | | AABBCCDDAABBCC | +------------------+
03 Run get-distribution-config command (OSX/Linux/UNIX) using the ID of the Amazon CloudFront distribution that you want to examine as the identifier parameter, to describe the ID of the field-level encryption configuration defined for the cache behavior(s) associated with the selected distribution:
aws cloudfront get-distribution-config --id ABCDABCDABCDAB --query 'DistributionConfig.CacheBehaviors.Items[*].FieldLevelEncryptionId'
04 The command output should return the requested configuration ID:
[ "" ]
If the get-distribution-config command output returns and empty string (i.e. ""), as shown in the example above, the field-level encryption is not enabled for the associated cache behavior(s), therefore the selected Amazon Cloudfront distribution is not configured to encrypt private content at the edge locations.
05 Repeat step no. 3 and 4 for each CloudFront distribution deployed in your AWS cloud account.
Remediation / Resolution
To enable and configure field-level encryption for your Amazon CloudFront distributions, perform the following operations:
Using Terraform (AWS Provider)
01 Terraform configuration file (.tf):
terraform { required_providers { aws = { source = "hashicorp/aws" version = "~> 4.0" } } required_version = ">= 0.14.9" } provider "aws" { profile = "default" region = "us-east-1" } resource "aws_cloudfront_public_key" "cloudfront-public-key" { name = "cc-encrypted-public-key" encoded_key = file("public_key.pem") } resource "aws_cloudfront_field_level_encryption_profile" "field-level-encryption-profile" { name = "cc-field-level-encryption-profile" encryption_entities { items { public_key_id = aws_cloudfront_public_key.cloudfront-public-key.id provider_id = "trendmicro.com" field_patterns { items = ["DateOfBirth"] } } } } resource "aws_cloudfront_field_level_encryption_config" "field-level-encryption-config" { comment = "Amazon CloudFront field-level encryption configuration" content_type_profile_config { forward_when_content_type_is_unknown = true content_type_profiles { items { content_type = "application/x-www-form-urlencoded" format = "URLEncoded" } } } query_arg_profile_config { forward_when_query_arg_profile_is_unknown = true query_arg_profiles { items { profile_id = aws_cloudfront_field_level_encryption_profile.field-level-encryption-profile.id query_arg = "ArgOne" } } } } resource "aws_cloudfront_distribution" "cloudfront-distribution" { enabled = true default_root_object = "index.html" comment = "CloudFront CDN Web Distribution" origin { domain_name = "domain.com" origin_id = "cc-cdn-origin" custom_origin_config = { http_port = 80 https_port = 443 origin_ssl_protocols = ["TLSv1.2"] origin_protocol_policy = "https-only" } } default_cache_behavior { compress = true target_origin_id = "cc-domain-origin" allowed_methods = ["GET", "HEAD"] cached_methods = ["GET", "HEAD"] forwarded_values { query_string = false cookies { forward = "none" } } min_ttl = 0 default_ttl = 3600 max_ttl = 86400 viewer_protocol_policy = "https-only" } viewer_certificate { cloudfront_default_certificate = true } price_class = "PriceClass_All" field_level_encryption_id = aws_cloudfront_field_level_encryption_config.field-level-encryption-config.id }
Using AWS Console
01 Create an RSA key pair. Use OpenSSL or another tool to create your own key pair.
02 Sign in to the AWS Management Console.
03 Navigate to Amazon CloudFront console at https://console.aws.amazon.com/cloudfront/v3/.
04 In the left navigation panel, under Key management, choose Public keys.
05 Choose Create public key to initiate the key setup process.
06 On the Create public key page, perform the following actions:
- In the Namebox, enter a unique name for your new public key.
- In the Description – optional box, provide an optional description.
- In the Key box, paste the encoded key value for your public key, generated at step no. 1. The key value must include the "-----BEGIN PUBLIC KEY-----" and "-----END PUBLIC KEY-----" lines.
- Choose Create public key to add your new public key.
07 In the left navigation panel, under Security, choose Field-level encryption and select the Profiles tab.
08 Choose Create encryption profile to start the field-level encryption profile setup.
09 On the Create encryption profile page, provide the following information:
- Enter a unique name for the new field-level encryption profile in the Name box.
- In the Description – optional box, provide a short description to help identify this field-level encryption profile.
- Select the name of a public key created earlier in the Remediation process from Public key name dropdown list.
- For Provider name, type a phrase to help identify the key, such as the provider where you got the key pair.
- For Encryption fields, use the Add item button to add the data fields for Amazon CloudFront to encrypt with this key before forwarding the request to your origin.
- Choose Create encryption profile to save the changes and create the new field-level encryption profile.
10 In the left navigation panel, under Security, choose Field-level encryption and select the Configurations tab.
11 Choose Create configuration to initiate the encryption configuration setup.
12 On the Create configuration page, perform the following actions:
- Select the newly created field-level encryption profile from the Encryption profile ID dropdown list.
- In the Description – optional box, provide a short description to help identify this field-level encryption configuration.
- Under Forward requests when the content type doesn’t match, select the Forward requests checkbox. If the request's content type doesn't match the one specified for this configuration (i.e. application/x-www-form-urlencoded), this option forwards the request to the origin anyway, without encrypting the data fields. If requests are not forwarded, Amazon CloudFront returns an error.
- Choose Additional settings. Under Forward requests when the query string value doesn’t match, select the Forward requests checkbox. If the value of the field-level encryption profile query string doesn't match an encryption profile for this configuration, forward the request to the origin anyway, without encrypting the data fields. If requests are not forwarded, Amazon CloudFront returns an error.
- Choose Create configuration to create the new field-level encryption configuration to associate with the cache behavior defined for your CloudFront distribution.
13 In the left navigation panel, under CloudFront, choose Distributions.
14 Click on the name of the Amazon CloudFront distribution that you want to reconfigure.
15 Select the Behaviors tab to access the cache behavior(s) configured for the selected distribution.
16 Select the cache behavior that you want to reconfigure and choose Edit.
17 On the Edit behavior configuration page, select the identifier of the field-level encryption configuration created at step no. 12 from the Field-level encryption dropdown list. You can set the field-level encryption configuration only when the Viewer protocol policy and the Origin protocol policy settings are using HTTPS.
18 Choose Save changes to apply the changes and enable the field-level encryption for the selected Amazon CloudFront distribution.
19 Repeat steps no. 16 – 18 for each cache behavior associated with the selected distribution.
20 Repeat steps no. 14 – 19 for each CloudFront distribution available within your AWS cloud account.
Using AWS CLI
01 Create an RSA key pair. Use OpenSSL or another tool to create your own key pair.
02 Run create-public-key command (OSX/Linux/UNIX) using the encoded public key value (including -----BEGIN PUBLIC KEY-----and-----END PUBLIC KEY-----) generated at the previous step as command parameter to create a public key for Amazon CloudFront to use for field-level encryption:
aws cloudfront create-public-key --region us-east-1 --public-key-config CallerReference="1234567890123",Name="cc-encryption-public-key",EncodedKey="-----BEGIN PUBLIC KEY----- ... -----END PUBLIC KEY-----",Comment="Public key for CloudFront field-level encryption."
03 The command output should return the command request metadata:
{ "PublicKey": { "CreatedTime": "2021-09-10T11:30:41.223Z", "Id": "ABCD1234ABCDA", "PublicKeyConfig": { "Comment": "Public key for CloudFront field-level encryption.", "EncodedKey": "-----BEGIN PUBLIC KEY----- ... -----END PUBLIC KEY-----\n", "CallerReference": "1234567890123", "Name": "cc-encryption-public-key" } }, "ETag": "AABBAABBAABBA", "Location": "https://cloudfront.amazonaws.com/2018-06-18/public-key/ABCD1234ABCDA" }
04 Define the required parameters for the create-field-level-encryption-profile command and save the document to a file named field-level-encryption-profile.json. Replace the necessary configuration details, such as "PublicKeyId" parameter value, returned at the previous step, with your own details:
{ "Name": "cc-field-level-encryption-profile", "CallerReference": "1234567890123", "Comment": "CloudFront field-level encryption profile.", "EncryptionEntities": { "Quantity": 1, "Items": [ { "PublicKeyId": "ABCD1234ABCDA", "ProviderId": "cloudconformity.com", "FieldPatterns": { "Quantity": 2, "Items": ["UserName", "CreditCard"] } } ] } }
05 Run create-field-level-encryption-profile command (OSX/Linux/UNIX) using the parameters defined at the previous step to create the required Amazon CloudFront field-level encryption profile:
aws cloudfront create-field-level-encryption-profile --field-level-encryption-profile-config file://field-level-encryption-profile.json
06 The command output should return the command request metadata:
{ "FieldLevelEncryptionProfile": { "LastModifiedTime": "2021-09-10T12:39:51.343Z", "FieldLevelEncryptionProfileConfig": { "Comment": "CloudFront field-level encryption profile.", "EncryptionEntities": { "Items": [ { "FieldPatterns": { "Items": [ "CreditCard", "UserName" ], "Quantity": 2 }, "ProviderId": "cloudconformity.com", "PublicKeyId": "ABCD1234ABCDA" } ], "Quantity": 1 }, "CallerReference": "1234567890123", "Name": "cc-field-level-encryption-profile" }, "Id": "1234AABB1234CC" }, "ETag": "AAABBBCCCDDDA", "Location": "https://cloudfront.amazonaws.com/2018-06-18/field-level-encryption-profile/1234AABB1234CC" }
07 Define the parameters for the create-field-level-encryption-config command and save the JSON document to a file named field-level-encryption-config.json. Replace the necessary configuration details, such as "ProfileId" parameter value (i.e. the ID of the field-level encryption profile), with your own configuration details:
{ "CallerReference": "1234567890123", "Comment": "CloudFront field-level encryption configuration", "QueryArgProfileConfig": { "ForwardWhenQueryArgProfileIsUnknown": false, "QueryArgProfiles": { "Quantity": 0, "Items": [] } }, "ContentTypeProfileConfig": { "ForwardWhenContentTypeIsUnknown": false, "ContentTypeProfiles": { "Quantity": 1, "Items": [ { "Format": "URLEncoded", "ProfileId": "1234AABB1234CC", "ContentType": "application/x-www-form-urlencoded" } ] } } }
08 Run create-field-level-encryption-config command (OSX/Linux/UNIX) using the parameters defined at the previous step to create the field-level encryption configuration that will be associated with your Amazon CloudFront distribution:
aws cloudfront create-field-level-encryption-config --field-level-encryption-config file://field-level-encryption-config.json
09 The command output should return the create-field-level-encryption-config command request metadata (including the field-level encryption configuration ID):
{ "FieldLevelEncryption": { "LastModifiedTime": "2021-09-10T12:45:03.500Z", "Id": "AB1234CD1234AB", "FieldLevelEncryptionConfig": { "Comment": "CloudFront field-level encryption configuration.", "QueryArgProfileConfig": { "ForwardWhenQueryArgProfileIsUnknown": false, "QueryArgProfiles": { "Items": [], "Quantity": 0 } }, "ContentTypeProfileConfig": { "ContentTypeProfiles": { "Items": [ { "ProfileId": "1234AABB1234CC", "ContentType": "application/x-www-form-urlencoded", "Format": "URLEncoded" } ], "Quantity": 1 }, "ForwardWhenContentTypeIsUnknown": false }, "CallerReference": "1234567890123" } }, "ETag": "AAAAAAABBBBBBB", "Location": "https://cloudfront.amazonaws.com/2018-06-18/field-level-encryption/AB1234CD1234AB" }
10 Run get-distribution-config command (OSX/Linux/UNIX) to extract all the configuration information from the Amazon CloudFront distribution that you want to reconfigure:
aws cloudfront get-distribution-config --id ABCDABCDABCDAB --query 'DistributionConfig'
11 The command output should return the requested configuration information:
{ "CallerReference": "abcd1234-abcd-1234-abcd-1234abcd1234", "Aliases": { "Quantity": 0 }, "DefaultRootObject": "", "Origins": { "Quantity": 1, "Items": [ { "Id": "cloudconformity.com", "DomainName": "cloudconformity.com", "OriginPath": "", "CustomHeaders": { "Quantity": 0 }, "CustomOriginConfig": { "HTTPPort": 80, "HTTPSPort": 443, "OriginProtocolPolicy": "http-only", "OriginSslProtocols": { "Quantity": 3, "Items": [ "TLSv1", "TLSv1.1", "TLSv1.2" ] }, "OriginReadTimeout": 30, "OriginKeepaliveTimeout": 5 }, "ConnectionAttempts": 3, "ConnectionTimeout": 10, "OriginShield": { "Enabled": false } } ] }, "OriginGroups": { "Quantity": 0 }, "DefaultCacheBehavior": { "TargetOriginId": "cloudconformity.com", "TrustedSigners": { "Enabled": false, "Quantity": 0 }, "TrustedKeyGroups": { "Enabled": false, "Quantity": 0 }, "ViewerProtocolPolicy": "allow-all", "AllowedMethods": { "Quantity": 2, "Items": [ "HEAD", "GET" ], "CachedMethods": { "Quantity": 2, "Items": [ "HEAD", "GET" ] } }, "SmoothStreaming": false, "Compress": false, "LambdaFunctionAssociations": { "Quantity": 0 }, "FunctionAssociations": { "Quantity": 0 }, "FieldLevelEncryptionId": "", "ForwardedValues": { "QueryString": false, "Cookies": { "Forward": "none" }, "Headers": { "Quantity": 0 }, "QueryStringCacheKeys": { "Quantity": 0 } }, "MinTTL": 0, "DefaultTTL": 86400, "MaxTTL": 31536000 }, "CacheBehaviors": { "Quantity": 1, "Items": [ { "PathPattern": "/images", "TargetOriginId": "cloudconformity.com", "TrustedSigners": { "Enabled": false, "Quantity": 0 }, "TrustedKeyGroups": { "Enabled": false, "Quantity": 0 }, "ViewerProtocolPolicy": "allow-all", "AllowedMethods": { "Quantity": 2, "Items": [ "HEAD", "GET" ], "CachedMethods": { "Quantity": 2, "Items": [ "HEAD", "GET" ] } }, "SmoothStreaming": false, "Compress": false, "LambdaFunctionAssociations": { "Quantity": 0 }, "FunctionAssociations": { "Quantity": 0 }, "FieldLevelEncryptionId": "", "ForwardedValues": { "QueryString": false, "Cookies": { "Forward": "none" }, "Headers": { "Quantity": 0 }, "QueryStringCacheKeys": { "Quantity": 0 } }, "MinTTL": 0, "DefaultTTL": 86400, "MaxTTL": 31536000 } ] }, "CustomErrorResponses": { "Quantity": 0 }, "Comment": "", "Logging": { "Enabled": false, "IncludeCookies": false, "Bucket": "", "Prefix": "" }, "PriceClass": "PriceClass_100", "Enabled": true, "ViewerCertificate": { "CloudFrontDefaultCertificate": true, "MinimumProtocolVersion": "TLSv1", "CertificateSource": "cloudfront" }, "Restrictions": { "GeoRestriction": { "RestrictionType": "none", "Quantity": 0 } }, "WebACLId": "", "HttpVersion": "http1.1", "IsIPV6Enabled": false }
12 Run get-distribution-config command (OSX/Linux/UNIX) to describe the current version of the configuration available for the selected distribution (i.e. eTag):
aws cloudfront get-distribution-config --id ABCDABCDABCDAB --query 'ETag'
13 The command output should return the requested information:
"AAAABBBBCCCCD"
14 Modify the configuration document returned at step no. 11 to enable field-level encryption by adding the ID of the field-level encryption configuration returned at step no. 9 to the "FieldLevelEncryptionId" propery (as highlighted in the example below). Save the document with the modified distribution configuration to a JSON file named enable-field-level-encryption.json. You can set the field-level encryption configuration only when "ViewerProtocolPolicy" and "OriginProtocolPolicy" are set to "https-only":
{ "CallerReference": "abcd1234-abcd-1234-abcd-1234abcd1234", "Aliases": { "Quantity": 0 }, "DefaultRootObject": "", "Origins": { "Quantity": 1, "Items": [ { "Id": "cloudconformity.com", "DomainName": "cloudconformity.com", "OriginPath": "", "CustomHeaders": { "Quantity": 0 }, "CustomOriginConfig": { "HTTPPort": 80, "HTTPSPort": 443, "OriginProtocolPolicy": "http-only", "OriginSslProtocols": { "Quantity": 3, "Items": [ "TLSv1", "TLSv1.1", "TLSv1.2" ] }, "OriginReadTimeout": 30, "OriginKeepaliveTimeout": 5 }, "ConnectionAttempts": 3, "ConnectionTimeout": 10, "OriginShield": { "Enabled": false } } ] }, "OriginGroups": { "Quantity": 0 }, "DefaultCacheBehavior": { "TargetOriginId": "cloudconformity.com", "TrustedSigners": { "Enabled": false, "Quantity": 0 }, "TrustedKeyGroups": { "Enabled": false, "Quantity": 0 }, "ViewerProtocolPolicy": "allow-all", "AllowedMethods": { "Quantity": 2, "Items": [ "HEAD", "GET" ], "CachedMethods": { "Quantity": 2, "Items": [ "HEAD", "GET" ] } }, "SmoothStreaming": false, "Compress": false, "LambdaFunctionAssociations": { "Quantity": 0 }, "FunctionAssociations": { "Quantity": 0 }, "FieldLevelEncryptionId": "AB1234CD1234AB", "ForwardedValues": { "QueryString": false, "Cookies": { "Forward": "none" }, "Headers": { "Quantity": 0 }, "QueryStringCacheKeys": { "Quantity": 0 } }, "MinTTL": 0, "DefaultTTL": 86400, "MaxTTL": 31536000 }, "CacheBehaviors": { "Quantity": 1, "Items": [ { "PathPattern": "/images", "TargetOriginId": "cloudconformity.com", "TrustedSigners": { "Enabled": false, "Quantity": 0 }, "TrustedKeyGroups": { "Enabled": false, "Quantity": 0 }, "ViewerProtocolPolicy": "allow-all", "AllowedMethods": { "Quantity": 2, "Items": [ "HEAD", "GET" ], "CachedMethods": { "Quantity": 2, "Items": [ "HEAD", "GET" ] } }, "SmoothStreaming": false, "Compress": false, "LambdaFunctionAssociations": { "Quantity": 0 }, "FunctionAssociations": { "Quantity": 0 }, "FieldLevelEncryptionId": "AB1234CD1234AB", "ForwardedValues": { "QueryString": false, "Cookies": { "Forward": "none" }, "Headers": { "Quantity": 0 }, "QueryStringCacheKeys": { "Quantity": 0 } }, "MinTTL": 0, "DefaultTTL": 86400, "MaxTTL": 31536000 } ] }, "CustomErrorResponses": { "Quantity": 0 }, "Comment": "", "Logging": { "Enabled": false, "IncludeCookies": false, "Bucket": "", "Prefix": "" }, "PriceClass": "PriceClass_100", "Enabled": true, "ViewerCertificate": { "CloudFrontDefaultCertificate": true, "MinimumProtocolVersion": "TLSv1", "CertificateSource": "cloudfront" }, "Restrictions": { "GeoRestriction": { "RestrictionType": "none", "Quantity": 0 } }, "WebACLId": "", "HttpVersion": "http1.1", "IsIPV6Enabled": false }
15 Run update-distribution command (OSX/Linux/UNIX) using the document modified at the previous step (i.e. enable-field-level-encryption.json) as the distribution configuration document, to reconfigure the selected Amazon CloudFront distribution in order to enable field level encryption. --if-match parameter represents the current version of the configuration, returned at step no. 4:
aws cloudfront update-distribution --id ABCDABCDABCDAB --if-match AAAABBBBCCCCD --distribution-config file://enable-field-level-encryption.json --query 'Distribution.Status'
16 The command output should return the status of the modified CloudFront distribution:
"InProgress"
17 Repeat steps no. 10 – 16 for each Amazon CloudFront distribution deployed in your AWS cloud account.
References
- AWS Documentation
- Amazon CloudFront FAQs
- Overview of distributions
- Configuring secure access and restricting access to content
- Using field-level encryption to help protect sensitive data
- AWS Command Line Interface (CLI) Documentation
- cloudfront
- list-distributions
- get-distribution
- create-public-key
- create-field-level-encryption-profile
- create-field-level-encryption-config
- update-distribution