AWS CloudFront

This module is made for AWS CloudFront distributions, using the AWS CloudFront Lambda@Edge service.

Compatibility

We provide integrations for two types of Lambda runtimes:

  • Node.js 16+
  • Python 3.9+

Installation

Prerequisites

AWS IAM permissions

In order to associate your Lambda@Edge function with your CloudFront distribution and be able to record logs, you need to create IAM permissions and roles based on the snippet below.

  1. Access to the Identity and Access Management (IAM) page, in the Policies tab.
  2. Click on the Create policy button.
  3. Select JSON in the Policy editor, and paste the following permissions:
{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Sid": "VisualEditor0",
            "Effect": "Allow",
            "Action": [
                "iam:CreateServiceLinkedRole",
                "lambda:GetFunction",
                "cloudfront:UpdateDistribution",
                "lambda:EnableReplication"
            ],
            "Resource": "*"
        },
        {
          "Effect": "Allow",
          "Action": [
            "logs:CreateLogGroup",
            "logs:CreateLogStream",
            "logs:PutLogEvents"
          ],
          "Resource": [
            "*"
          ]
        }
    ]
}
  1. Then click on the Next button, enter a name for this policy, and click on the Save button.
Form to create the policy

Form to create the policy

  1. Access the IAM page, in the Role tab.
  2. Click on the Create role button.
  3. Select the Trusted entity type to AWS service, select the Use case to Lambda, and click on the Next button.
Form to select the trusted entity type and the use case

Form to select the trusted entity type and the use case

  1. Select the IAM policy created on step 4 and click on the Next button.
Capture d’écran 2024-08-05 à 11.30.46.png

Attach the permission on the new role

  1. Enter a name for this role, and click on the Create role button.
Untitled

Form to create the role

  1. Click on the Trust relationships tab and Edit the trust relationship.
Untitled

Trust relationships tab

  1. Paste the following trusted service principals to assume function execution role for your Lambda@Edge:
{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Effect": "Allow",
      "Principal": {
        "Service": [
          "lambda.amazonaws.com",
          "edgelambda.amazonaws.com"
        ]
      },
      "Action": "sts:AssumeRole"
    }
  ]
}

Configuration of the CloudFront distribution

If you don’t already have one, refer to this AWS documentation to create a CloudFront distribution.

Create a custom error 403 response

This disables the caching of responses with 403 http code.

  1. Access your CloudFront distribution page in the Error pages tab, and click on Create custom error response button.
Capture d’écran 2024-08-22 à 11.31.23.png

Create a new custom error response

  1. In the Create custom error response page, set the following properties:
    1. Select HTTP code 403.
    2. Set minimal TTL 0.
    3. Check no for Customize error response.
Capture d’écran 2024-08-22 à 11.31.58.png

Form to create a new custom error response

  1. Click on the Create custom error response button.

Configure the distribution’s default behavior

This defines the default behavior of the CloudFront distribution.

  1. Access your CloudFront distribution page in the Behavior tab, and edit the default behavior
Capture d’écran 2024-08-13 à 11.55.33.png

Edit the default behavior

  1. In the Cache key and origin requests section, select Cache policy and origin request policy set the Origin request policy to AllViewerExceptHostHeader.
  2. Click on the Save changes button at the end of the page.

Configuration of the AWS Lambda@Edge function

In this section, you will create and configure the AWS Lambda@Edge function to intercept incoming requests and validate them with our service.

Can I re-use an existing Lamdba@Edge function?

Yes, it is possible to call and configure the Lambda@Edge function through an existing one.

Refer to the advanced configuration section to use an existing Lambda@Edge function.

  1. Connect to your AWS console and go to the Lambda@Edge homepage.
  2. Create a new Lambda@Edge function

The function must be created on the us-east-1 region.

AWS automatically selects the us-east-1 region when you access the Lambda@Edge portal.

Please don't change the region.

  1. Click on the Create function button, then select Author from scratch.
Untitled

Create a new Lambda function

  1. In the Basic information section:
    1. Enter a name for your Lambda function, e.g. DataDomeModule-{YOUR WEBSITE NAME}.
    2. Select Node.js 20.x or Python 3.12 for the runtime.
    3. Click on Create function button.
Untitled

Set the basic information of the Lambda function

  1. In the Code source tab:
  • Choose Upload a file from Amazon S3 and paste the following URL for the selected module.
https://s3.amazonaws.com/dd-lambda-edge/datadome-lambda-edge-latest.zip
https://s3.amazonaws.com/dd-lambda-edge/datadome-lambda-edge-py-latest.zip
Untitled

Upload a file from an Amazon S3 location

  1. Open the datadome.js file (for the Node.js runtime) or datadome.py (for the Python runtime)
  2. Replace YOUR_DATADOME_LICENSE_KEY with your own DataDome server-side key, available in your DataDome dashboard.
Untitled

Replace the DATADOME_LICENSE_KEY by your own DataDome server-side key

  1. Scroll down to the Runtime settings tab, click on Edit.
Untitled

Update the runtime settings

  1. In the Runtime settings page:
  • Enter datadome.handler (for the Node.js runtime) or datadome.lambda_handler (for the Python runtime) in the Handler field.
  • Click on Save button.
Untitled

Set the runtime and the handler for the Lambda function

  1. In the Configuration tab and General configuration menu, click on Edit.
Untitled

Update the general configuration of your Lambda function

  1. In the Edit basic settings page:
  • Set Timeout to 0 min 1 sec.
  • Select an existing role with the required permissions.
  • Click on Save.
Untitled

Update the basic settings of your lambda function

  1. Click on Actions and select Deploy to Lambda@Edge.
Capture d’écran 2024-08-05 à 15.24.58.png

Deploy to Lambda@Edge

  1. In the Deploy to Lambda@Edge window, provide the following configuration:
  • Select the CloudFront distribution that will send events to the Lambda function.
  • Select the default Cache behavior (*).
  • Select Viewer Request for CloudFront Event.
  • Do not check the Include body box.
  • Check the Confirm deploy to Lambda@Edge box.
  • Click on Deploy button.
Capture d’écran 2024-08-05 à 15.36.43.png

Configure the deployment of the Lambda@Edge

Can I associate the Lambda function to the CloudFront distribution on origin request?

No. Protection is not operational when the Lambda function is associated with origin request.

CloudFront will cache requests, even if the caching is completely disabled.

Most of the requests will be executed by the AWS caching mechanism, with modified headers (like user-agent: Amazon CloudFront), and will not be intercepted by the DataDome module.

If there is already another function associated with theviewer request event, refer to the use of an existing lambda function to merge them.

Congrats! You can now see your traffic in your DataDome dashboard.

You can refer to the recommended configuration below to enhance the protection of your CloudFront distribution.

Recommended configuration

Disable CloudFront caching for requests protected by DataDome

If you are caching dynamic requests (not javascript, css, images) at CloudFront level and these requests are protected by DataDome, you must change your backend origin to ask CloudFront to not cache these requests if they contain a set-cookie in the response.

Indeed, by default CloudFront will cache http requests even if the backend returned a cookie. It can lead to unexpected bot detection issue. Your backend/origin needs to return this header : Cache-Control: no-cache="Set-Cookie".

You can find more information about this CloudFront behavior in AWS Documentation, in the Disable caching of Set-Cookie headers section.

If you were caching files that were also protected by DataDome, you may want to invalidate the cache by following this CloudFront documentation.

Include Client Hints in request headers

Client Hints can be collected by the DataDome module to enhance the detection.

For these values to be defined by the browser, Accept-CH header must be sent by the origin. You can achieve this by using a response header policy .

  1. Access to the CloudFront distribution that you want to configure.
  2. In the Cache key and origin requests section, on the Response headers policy part click on the Create response headers policy to enable HTTP Client hints.
Create a new response headers policy

Create a new response headers policy

  1. In the Create response headers policy tab, set the following:
  • On Details section, set the response headers policy’s name: Accept-CH.
  • On Custom headers section, click on the Add header button.
  • Set the following values for the new custom header:
    • Name: Accept-CH.
    • Value: Sec-CH-UA,Sec-CH-UA-Mobile,Sec-CH-UA-Platform,Sec-CH-UA-Arch,Sec-CH-UA-Full-Version-List,Sec-CH-UA-Model,Sec-CH-Device-Memory.
    • Check yes for the Origin override.
  • Click on Create button at the end of the page.
The custom response headers policy

The custom response headers policy

  1. Back to the CloudFront distribution page, refresh the response headers policy’s list and select your Accept-CH custom header.
Capture d’écran 2024-08-22 à 11.55.54.png

Attach the response headers policy

  1. Click on Save changes button at the end of the page.

Associate the Lambda@Edge with non-default distribution behaviors

By default, the Lambda@Edge is associated with the default behavior of the distribution you selected, meaning that the requests going through other behaviors, which are ranked higher, will not be protected.

  1. Access the CloudFront distribution console that you want to configure.
  2. Click on Behaviors.
  3. Select one of the behaviors you want to protect, and click on Edit.
Edit behaviors

Edit behaviors

  1. Associate the Lambda@Edge function on the Viewer Request and copy the DataDome Lambda@Edge ARN, which includes the version number.
Associate Lambda@Edge

Associate Lambda@Edge

  1. Click on Save changes.

Advanced configuration

Settings

By default, the configuration is located in the first code block of the datadome.js(or datadome.py) file.

Refer to the list below for the possible configuration settings.

SettingDescriptionRequiredDefault
DATADOME_LICENSE_KEYYour DataDome server side key, found in your Dashboard.Yes
DATADOME_TIMEOUTThe request timeout to DataDome API, in milliseconds.Optional300
DATADOME_URI_REGEXRegular expression to include URIs in the DataDome analysed traffic.Optional
DATADOME_URI_REGEX_EXCLUSIONRegular expression to exclude URIs from the DataDome analysed traffic.OptionalList of excluded static assets below
DATADOME_LOG_BOT_INFOBoolean to log the requests' bot information in CloudWatch. Refer to the Log enrichment header section.Optionalfalse
DATADOME_ENABLE_GRAPHQL_SUPPORTBoolean to enable GraphQL support. Refer to Enable GraphQL support section.Optionalfalse

Can I dynamically configure the module?

It is not possible to use environment variables in Lambda@Edge due to an AWS limitation - see Restrictions on edge functions.

However you can still follow the steps to configure the module from another function file and override a configuration depending on AWS Secrets Manager for instance.

Enable GraphQL support

Since version 1.19.0 of Lambda@Edge Node.js module, it is possible to enable GraphQL support:

  1. Change the value of DATADOME_ENABLE_GRAPHQL_SUPPORT to true inside the datadome.js:
const DATADOME_ENABLE_GRAPHQL_SUPPORT = true;
  1. Configure the CloudFront distribution behavior:
  • Allow POST methods.
Untitled

Allow POST methods on your CloudFront distribution

  • Include the body of the request in your CloudFront distribution on the Lambda@Edge’s viewer request by checking the corresponding box in the Edit Behavior - Function association section.
Include the body on the Lambda@Edge viewer request

Include the body on the Lambda@Edge viewer request

  • Click on Save changes button.

Protect only a part of a CloudFront Distribution

To protect only a part of a CloudFront Distribution, select one of the possibilities below:

  • First option: set an exclusion based on file extension. Modify the value DATADOME_URI_REGEX_EXCLUSION inside datadome.js(or datadome.py) to exclude hits to the Datadome API. In this case, the Lambda@Edge function is still executed (and billed) at the Amazon infrastructure level.
  • Second option: set an exclusion based on the path. Define a behavior in your CloudFront Distribution and attach the Lambda@Edge only to the needed paths. In this case, there is no Lambda execution at Amazon infrastructure nor at Datadome API.

Use an existing Lambda@Edge function (only supported with Node.js)

From version 1.18.0 of the Node.js Lambda@Edge module, calling and configuring the module can be done from another file.

The following example explains how to update a handler in the index.js file.

  1. Import the DataDome code as mentioned above.
  2. Import the DataDome module inside your index.jsfile:
const datadome = require("./datadome.js");
  1. Configure the DataDome module inside your index.jsfile:
// Configure DataDome module
const configuration = {
  serverSideKey:        'serverSideKeyValue',
  timeout:              300,
  maxSockets:           100,
  debug:                false,
  urlPatternInclusion:  null,
  urlPatternExclusion:  /\\.(avi|flv|mka|mkv|mov|mp4|mpeg|mpg|mp3|flac|ogg|ogm|opus|wav|webm|webp|bmp|gif|ico|jpeg|jpg|png|svg|svgz|swf|eot|otf|ttf|woff|woff2|css|less|js|map)$/i
};
datadome.configure(configuration);

💡

Update the configuration values (only serverSideKey is mandatory)

Other keys are shown with their default values.

  1. Update your handler from the index.jsfile to execute the DataDome protection:
exports.handler = (event, context, callback) => {
  // Call DataDome handler
  datadome.handler(event, context, callback);
  // [...]
}
  1. Ensure that the handler configured for this Lambda@Edge is index.handler in the Runtime settings section.

Upgrade

To update the code of the Lambda@Edge and publish a new version, apply the following steps:

  1. Select the lambda function to update.
  2. Store the active configuration of the module (List of possible configuration).
  3. Click Upload from then Amazon S3 location as shown below.
Upload new lambda function from Amazon S3 location

Upload new lambda function from Amazon S3 location

  1. Paste the right S3 location depending on the runtime used for the lambda and click on Save.
https://s3.amazonaws.com/dd-lambda-edge/datadome-lambda-edge-latest.zip
https://s3.amazonaws.com/dd-lambda-edge/datadome-lambda-edge-py-latest.zip
Paste the S3 location of the lambda

Paste the S3 location of the lambda

  1. Replace YOUR_DATADOME_LICENSE_KEY with your DataDome server-side key, available in your DataDome dashboard.
  2. Restore other specific configurations stored during Step 2.
  3. Click to Actions and Deploy to Lamda@Edge to deploy this up-to-date version.
Deploy to Lambda@Edge

Deploy to Lambda@Edge

  1. Select the CloudFront distribution and click Deploy.
Deploy the Lambda@Edge function on CloudFront distribution

Deploy the Lambda@Edge function on CloudFront distribution

FAQ

How can I integrate DataDome on a multi-account architecture?

If you have multiple CloudFront distributions deployed on different AWS accounts, one Lambda@Edge function per account is required.

You must repeat the configuration of the CloudFront distribution and the configuration of the Lambda@Edge function section for each of your distributions.

Can I get Bot NameRule Type and Bot/Human flags in my application?

The DataDome module can inject headers in HTTP requests received by your application.

The list of all exposed headers is available in our Log Enrichment page.

These headers will be recorded in your CloudWatch logs.

Can I integrate DataDome on CloudFront Functions?

It is not possible to set up DataDome inside CloudFront Functions as they do not provide network access to call third-party APIs - see Restrictions on CloudFront Functions.