Skip to content

Commit

Permalink
feat(cloudfront): Add support for response headers policy (aws#17359)
Browse files Browse the repository at this point in the history
feat(cloudfront): Add support for response headers policy

closes aws#17290 

Notes:
~1. Currently the CFNSpec is not up-to-date with the latest available cloudformation changes for `ResponseHeadersPolicyId` in `AWS::CloudFront::Distribution CacheBehavior`. Some aspects of the same are added to the PR but are left commented. Would update the PR once the spec is updated.~

Refs:
1. https://docs.aws.amazon.com/AmazonCloudFront/latest/DeveloperGuide/adding-response-headers.html
2. https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-cloudfront-responseheaderspolicy.html
3. https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-cloudfront-distribution-cachebehavior.html#cfn-cloudfront-distribution-cachebehavior-responseheaderspolicyid

----

*By submitting this pull request, I confirm that my contribution is made under the terms of the Apache-2.0 license*
  • Loading branch information
ayush987goyal authored and Andrew Beresford committed Nov 29, 2021
1 parent 60a18c2 commit b800c91
Show file tree
Hide file tree
Showing 9 changed files with 722 additions and 2 deletions.
52 changes: 52 additions & 0 deletions packages/@aws-cdk/aws-cloudfront/README.md
Expand Up @@ -260,6 +260,58 @@ new cloudfront.Distribution(this, 'myDistCustomPolicy', {
});
```

### Customizing Response Headers with Response Headers Policies

You can configure CloudFront to add one or more HTTP headers to the responses that it sends to viewers (web browsers or other clients), without making any changes to the origin or writing any code.
To specify the headers that CloudFront adds to HTTP responses, you use a response headers policy. CloudFront adds the headers regardless of whether it serves the object from the cache or has to retrieve the object from the origin. If the origin response includes one or more of the headers that’s in a response headers policy, the policy can specify whether CloudFront uses the header it received from the origin or overwrites it with the one in the policy.
See https://docs.aws.amazon.com/AmazonCloudFront/latest/DeveloperGuide/adding-response-headers.html

```ts
// Using an existing managed response headers policy
declare const bucketOrigin: origins.S3Origin;
new cloudfront.Distribution(this, 'myDistManagedPolicy', {
defaultBehavior: {
origin: bucketOrigin,
responseHeadersPolicy: cloudfront.ResponseHeadersPolicy.CORS_ALLOW_ALL_ORIGINS,
},
});

// Creating a custom response headers policy -- all parameters optional
const myResponseHeadersPolicy = new cloudfront.ResponseHeadersPolicy(this, 'ResponseHeadersPolicy', {
responseHeadersPolicyName: 'MyPolicy',
comment: 'A default policy',
corsBehavior: {
accessControlAllowCredentials: false,
accessControlAllowHeaders: ['X-Custom-Header-1', 'X-Custom-Header-2'],
accessControlAllowMethods: ['GET', 'POST'],
accessControlAllowOrigins: ['*'],
accessControlExposeHeaders: ['X-Custom-Header-1', 'X-Custom-Header-2'],
accessControlMaxAge: Duration.seconds(600),
originOverride: true,
},
customHeadersBehavior: {
customHeaders: [
{ header: 'X-Amz-Date', value: 'some-value', override: true },
{ header: 'X-Amz-Security-Token', value: 'some-value', override: false },
],
},
securityHeadersBehavior: {
contentSecurityPolicy: { contentSecurityPolicy: 'default-src https:;', override: true },
contentTypeOptions: { override: true },
frameOptions: { frameOption: cloudfront.HeadersFrameOption.DENY, override: true },
referrerPolicy: { referrerPolicy: cloudfront.HeadersReferrerPolicy.NO_REFERRER, override: true },
strictTransportSecurity: { accessControlMaxAge: Duration.seconds(600), includeSubdomains: true, override: true },
xssProtection: { protection: true, modeBlock: true, reportUri: 'https://example.com/csp-report', override: true },
},
});
new cloudfront.Distribution(this, 'myDistCustomPolicy', {
defaultBehavior: {
origin: bucketOrigin,
responseHeadersPolicy: myResponseHeadersPolicy,
},
});
```

### Validating signed URLs or signed cookies with Trusted Key Groups

CloudFront Distribution supports validating signed URLs or signed cookies using key groups.
Expand Down
8 changes: 8 additions & 0 deletions packages/@aws-cdk/aws-cloudfront/lib/distribution.ts
Expand Up @@ -12,6 +12,7 @@ import { IKeyGroup } from './key-group';
import { IOrigin, OriginBindConfig, OriginBindOptions } from './origin';
import { IOriginRequestPolicy } from './origin-request-policy';
import { CacheBehavior } from './private/cache-behavior';
import { IResponseHeadersPolicy } from './response-headers-policy';

// v2 - keep this import as a separate section to reduce merge conflict when forward merging with the v2 branch.
// eslint-disable-next-line
Expand Down Expand Up @@ -700,6 +701,13 @@ export interface AddBehaviorOptions {
*/
readonly originRequestPolicy?: IOriginRequestPolicy;

/**
* The response headers policy for this behavior. The response headers policy determines which headers are included in responses
*
* @default - none
*/
readonly responseHeadersPolicy?: IResponseHeadersPolicy;

/**
* Set this to true to indicate you want to distribute media files in the Microsoft Smooth Streaming format using this behavior.
*
Expand Down
1 change: 1 addition & 0 deletions packages/@aws-cdk/aws-cloudfront/lib/index.ts
Expand Up @@ -7,6 +7,7 @@ export * from './origin';
export * from './origin-access-identity';
export * from './origin-request-policy';
export * from './public-key';
export * from './response-headers-policy';
export * from './web-distribution';

export * as experimental from './experimental';
Expand Down
Expand Up @@ -48,6 +48,7 @@ export class CacheBehavior {
cachePolicyId: (this.props.cachePolicy ?? CachePolicy.CACHING_OPTIMIZED).cachePolicyId,
compress: this.props.compress ?? true,
originRequestPolicyId: this.props.originRequestPolicy?.originRequestPolicyId,
responseHeadersPolicyId: this.props.responseHeadersPolicy?.responseHeadersPolicyId,
smoothStreaming: this.props.smoothStreaming,
viewerProtocolPolicy: this.props.viewerProtocolPolicy ?? ViewerProtocolPolicy.ALLOW_ALL,
functionAssociations: this.props.functionAssociations?.map(association => ({
Expand Down

0 comments on commit b800c91

Please sign in to comment.