Deploy AWS Cloudfront and security headers with Terraform
I made a post in July 2021 regarding AWS CloudFront + security headers. Using AWS Cloudfront and Cloudfront Functions, security headers were injected in viewer responses; however, AWS Cloudfront natively supports security headers as of Nov. 2nd, 2021 alongside configurable CORS and custom HTTP response headers.
Security Headers
Cloudfront can natively support all the security headers from the last post:
- permissions-policy
- referrer-policy
- strict-transport-security
- x-content-type-options
- x-frame-options
- x-xss-protection
Terraform Code
Begin with defining an aws_cloudfront_response_headers_policy
resource in Terraform. This resources contains all the header policy information. In the following example, the values for each security_headers_config
were copied from AWS’s documentation.
1resource "aws_cloudfront_response_headers_policy" "headers_policy" {
2 name = "security-headers-policy"
3
4 custom_headers_config {
5 items {
6 header = "permissions-policy"
7 override = true
8 value = "accelerometer=(), camera=(), geolocation=(), gyroscope=(), magnetometer=(), microphone=(), payment=(), usb=()"
9 }
10 }
11
12 security_headers_config {
13 content_type_options {
14 override = true
15 }
16
17 frame_options {
18 override = true
19 frame_option = "DENY"
20 }
21
22 referrer_policy {
23 override = true
24 referrer_policy = "same-origin"
25 }
26
27 strict_transport_security {
28 override = true
29 access_control_max_age_sec = 63072000
30 include_subdomains = true
31 preload = true
32 }
33
34 xss_protection {
35 override = true
36 mode_block = true
37 protection = true
38 }
39 }
40}
Attach it to a Cloudfront Behavior. In this case, I attached it to the default_cache_behavior
block.
1locals {
2 cloudfront_origin_id = "s3"
3}
4
5resource "aws_cloudfront_distribution" "distribution" {
6 aliases = var.domain_names
7 enabled = true
8
9 origin {
10 domain_name = aws_s3_bucket.bucket.bucket_domain_name
11 origin_id = local.cloudfront_origin_id
12 }
13
14 default_cache_behavior {
15 allowed_methods = ["GET", "HEAD"]
16 cached_methods = ["GET", "HEAD"]
17 compress = true
18 target_origin_id = local.cloudfront_origin_id
19 viewer_protocol_policy = "redirect-to-https"
20 response_headers_policy_id = aws_cloudfront_response_headers_policy.headers_policy.id
21 }
22
23 restrictions {
24 geo_restriction {
25 restriction_type = "none"
26 }
27 }
28}
Once your infrastructure is deployed, AWS CloudFront will forward security headers. To see this in action, refer to the how.wtf
repository.