Fastly CDN (VCL)

DataDome Fastly module detects and protects against bot activity.

DataDome Bot protection can be integrated directly inside Fastly.

Before the regular Fastly process starts, a preflight request is performed on the closest DataDome endpoint. Depending on the API response, the module either blocks the request or lets Fastly proceed with the regular process.

The module has been implemented to ensure the best user experience: if any errors were to occur during the preflight, or if the timeout is reached, the module will automatically disable its blocking mechanism and allow the regular Fastly process to proceed.



You need to Contact Fastly support to enable some features to be able to use DataDome Bot Protection

Send an email :

  • To: [email protected]
  • Subject: Pragmas needed on Service XXXXXXXXXX for DataDome support
Dear Fastly Support:

In order to enable DataDome support please set these pragmas:
• fix_unsent_body_drain
• no_body_if_bereq_is_get_or_head

on the following service:


How to integrate DataDome Bot Protection inside Fastly ?

DataDome provides 3 integration options:

  • A. [Recommended] VCL snippets through the Fastly dashboard
  • B. Dynamic snippets through the Fastly API
  • C. Custom VCL through the Fastly dashboard

You can find the code here

A. VCL snippets through the Fastly dashboard


Before integrating DataDome, you need to ask Fastly Support to enable DataDome support for your Fastly service as described here.

  1. Create a Fastly service or use an existing one, then create a new version of this service by cloning the actual one.
  1. Go to VCL snippets
  1. Download and extract our Fastly module. Fastly snippets are available inside the snippet folder. Upload them one by one :
  2. Start with the init one.
    Update your own server server key (You can find it inside our dashboard) on line

  1. Do the same things from all others vcl snippets : recv, miss, pass, fetch, error and deliver).

For each one, you need to select the corresponding subroutine.

At the end you should have 7 snippets like this. Double check for each one the type is correct.

  1. Click activate to deploy the new Fastly configuration.
  1. You are now protected by DataDome

B. Regular VCL snippets with Terraform

You need to provide Terraform with your Fastly API key.
Follow the Fastly documentation to create it.

When you have your key, you must export a FASTLY_API_KEY environment variable in the shell from where you will launch Terraform commands
export FASTLY_API_KEY=<your API key>.

Next, you can open the Terraform file and edit the following sections:

  • Line 21: Input the DNS you want to use to access your service
  • Line 26: Provide a DNS or an IP to your origin backend. Warning: the backend must be named origin
provider "fastly" {}

locals {
  # Define all the datadome snippet names needed here
  datadome_snippets = toset([

# Create fastly service
resource "fastly_service_v1" "main" {
  name = "datadome_protected_service"

  domain {
    name    = ""
    comment = "Test"

  backend {
    address = ""
    name    = "origin"
    port    = 80

  # This dynamic block create a `snippet` block
  # for each datadome snippet defined in the locals
  dynamic "snippet" {
    for_each = local.datadome_snippets

    content {
      type    = snippet.value
      name    = format("datadome_%s", snippet.value)
      content = file(format("%s/%s.vcl", path.module, snippet.value))


Deploying the service for the first time

If you deploy this code for the first time, Terraform will fail on the plan stage, since the service needs to be created before we can provision the snippets code.
To deploy it for the first time you should first deploy the service and then the remaining code:

  • terraform apply -target fastly_service_v1.demo
  • terraform apply

C. Custom VCL

  1. Download the latest version of the module
  2. Connect to your Fastly console, and go to the Configuration tab
  3. Switch to Required Services
  4. Click configuration -> clone active

  1. Go to Origin -> Hosts
  2. Confirm that another upstream has the name origin
  3. Go to Custom VCL and click Upload your first VCL file

  1. Input name, for example datadome, and upload datadome.vcl from the distribution

  1. Click Create
  2. Go into the file and update the code at the Edit VCL block. You must replace your Server API Key (You can find it inside our Dashboard) near line 48

  1. Update Shield Backend Name with the actual name near line 460. If you don't use it, feel free to comment this line
  2. Click the Activate button on the top-right side


The Fastly module doesn't have a dedicated block for settings and you should update them in a different location in the file.

SettingLine numberComments
License key~48Your license key
TimeoutBackend configurationFastly uses standard varnish timeouts. You can find the details here
Regex~381Regex that should be matched or not matched to process the request in DataDome
datadome_restore_referrer~174Set to true to restore original referrer when a challenge is passed.


This only applies to custom VCL.
If you use shielding you should update the shield backend name and the region name inside the FASTLY recv. This is region specific, and the backend name depends on your use of SSL/TLS to connect to your upstream. All theses values are actual for 2020-03-04T12:12:44Z

NameConditionBackendSSL Backend
Ashburn - BWI-BWIshield_bwi_va_usssl_shield_bwi_va_us
Ashburn - DCA-DCAshield_dca_dc_usssl_shield_dca_dc_us
Atlanta - FTY-FTYshield_fty_ga_usssl_shield_fty_ga_us
Atlanta - PDK-PDKshield_pdk_ga_usssl_shield_pdk_ga_us
Cape Town-CPTshield_cpt_capetown_zassl_shield_cpt_capetown_za
Chicago - CHI-CHIshield_chi_il_usssl_shield_chi_il_us
Chicago - MDW-MDWshield_mdw_il_usssl_shield_mdw_il_us
Chicago - PWK-PWKshield_pwk_il_usssl_shield_pwk_il_us
Dallas - DAL-DALshield_dal_tx_usssl_shield_dal_tx_us
Frankfurt - Interxion-HHNshield_hhn_frankfurt_dessl_shield_hhn_frankfurt_de
Fujairah Al Mahta-FJRshield_fjr_aessl_shield_fjr_ae
Hong Kong-HKGshield_hongkong_hkssl_shield_hongkong_hk
London - LCY-LCYshield_london_city_ukssl_shield_london_city_uk
London - LON-LONshield_lon_london_ukssl_shield_lon_london_uk
London - Slough-LHRshield_london_ukssl_shield_london_uk
Los Angeles - BUR-BURshield_bur_ca_usssl_shield_bur_ca_us
Los Angeles - LAX-LAXshield_lax_ca_usssl_shield_lax_ca_us
New York City-JFKshield_jfk_ny_usssl_shield_jfk_ny_us
New York City - LGA-LGAshield_lga_ny_usssl_shield_lga_ny_us
Palo Alto-PAOshield_pao_ca_usssl_shield_pao_ca_us
San Jose-SJCshield_sjc_ca_usssl_shield_sjc_ca_us
Sao Paulo-GRUshield_gru_br_sassl_shield_gru_br_sa
Tokyo - HND-HNDshield_hnd_tokyo_jpssl_shield_hnd_tokyo_jp


  • Subject: Pragmas needed on Service XXXXXXXXXX for DataDome support
Dear Fastly Support:

In order to enable DataDome support please set these pragmas:
• fix_unsent_body_drain
• no_body_if_bereq_is_get_or_head

on the following service:


How to log the enriched headers?

Before any setup, please read carefully our requirements about the enriched headers.

  1. Setup a real-time logging providers
  2. Edit the log format. DataDome's headers are available in the req.http object. For example req.http.x-datadome-isbot.

Please, find below an example with Loggly:

    "fastly_is_edge":%{if(fastly.ff.visits_this_service == 0, "true", "false")}V,
    "response_reason":%{if(resp.response, "%22"+json.escape(resp.response)+"%22", "null")}V,
    "host":"%{if(req.http.Fastly-Orig-Host, req.http.Fastly-Orig-Host, req.http.Host)}V",

POST requests with a body are broken

You should ask Fastly Support to enable DataDome support for your Fastly service as described here.

How to integrate DataDome Bot Protection with Signal Sciences WAF

Both integrations can work together with a configuration change on the custom VCL's miss and pass subroutine snippets.

The call to edge_security that triggers Signal Sciences should only be done when the request is not being handled by DataDome, meaning that any call edge_security line should be replaced with the following piece of code:

  if (req.backend != datadome) {
    call edge_security;

Find below an example of how the generated final VCL should look like in the miss and pass subroutine snippets:

sub vcl_miss {
  if (req.backend != datadome) {
  	call edge_security;
# Snippet datadome_miss : 100

# Start of `miss.vcl` for DataDome-2.19.0
call set_origin_header;
# End of `miss.vcl` for DataDome-2.19.0


sub vcl_pass {
  if (req.backend != datadome) {
    call edge_security;
# Snippet datadome_pass : 100

# Start of `pass.vcl` for DataDome-2.19.0
call set_origin_header;
# End of `pass.vcl` for DataDome-2.19.0


How to restore the Referer request header after a challenge has been passed?

When passing a DataDome challenge on browsers other than Firefox, the referrer value is updated which can lead to inconsistent results in website analytics.

To restore the Referer header to its original value for your backend:

  • Contact our support team, they will review your requirements and provide you with the best recommendations.
  • Ensure that you have DataDome Fastly module version 2.20.4 or higher,
  • Set the boolean value of datadome_restore_referrer to true in the vcl_recv subroutine.
sub vcl_recv {
  # Configure the regular expression below to match URLs that
  # should be checked by DataDome
  declare local var.datadome_restore_referrer BOOL;
  # set var.datadome_restore_referrer = true; # uncomment to enable