> This page is for Applications Protection.

> For clean Markdown of any page, append .md to the page URL.
> For a complete documentation index, see https://docs.humansecurity.com/llms.txt.

# Manually install the Fastly VCL v12 Enforcer

If your organization uses **Fastly**, you can use HUMAN's **Fastly VCL Enforcer** to protect against malicious behavior. The Enforcer is deployed to your content delivery network (CDN) and dictates how traffic should be handled per your organization's standards.

You can learn how to install the Fastly VCL Enforcer with this article.

> **Warning**
>
> We **highly recommend** using the [Deploy Tool](/applications/general/deploy-tool) method instead of a manual installation if possible. See [Fastly VCL's primary installation article](/applications/fastly-vcl/v12/installation) for more information.

## Prerequisites

* A **Fastly account.** You can navigate to [Fastly’s website](https://www.fastly.com/) to create one.
* A **Fastly API token** with **global** scope (**not** global:read). You can find or generate one from the **Fastly dashboard > Account > Personal Profile > API tokens.**
* A **Fastly service** created on the CDN and set up with your organization’s necessary service configurations, such as **Domains** and **Origins**. You'll configure the Fastly Enforcer on this service. You can use an existing one or create a new service from Fastly’s dashboard by selecting **Create service > CDN.**
* Your unique HUMAN information:
  * Your **Application ID.** You can find this under **Platform Settings > Applications > Select an application > Application Settings > Application ID** in the  console. If you have multiple environments, you will also have multiple Application IDs, so be sure to choose the correct ID for the environment you want to install on.
  * Your **Server Token.** You can find this under **Platform Settings > Applications > Select an application > Application Settings > Server Token.**
  * Your **Risk Cookie Key.** You can find this under **Bot Defender > Policies > Policy Settings > Policy Information.**

## Contact Fastly and HUMAN

To install the Fastly Enforcer, you first need to do the following:

1. [Contact Fastly to enable HUMAN support](#contact-fastly)
2. [Contact HUMAN to receive necessary setup files](#contact-human)

### Contact Fastly

Fastly needs to activate certain functionality in your service so it works with the HUMAN Enforcer. Fastly is familiar with HUMAN and its Enforcer, so you can simply send them an email to enable it.

> **Note**
>
> This functionality must be manually activated by Fastly for each service you want to add the HUMAN Enforcer to, so you may need to send multiple service IDs.

1. From the Fastly dashboard, select the **service** you want to add the Enforcer to.
2. Copy the service’s **ID.**
3. Send an email to [support@fastly.com](mailto:support@fastly.com) with the following:
   * **Subject:** Please enable HUMAN support for our Fastly service
   * **Body:** Please enable HUMAN support for our service ID, `\<YOUR_ID_HERE>`, and confirm when it is completed.

Fastly will add the following pragmas to your service:

* `fix_unsent_body_drain`: Used to resolve an issue with HTTP response bodies not being fully sent to the client.
* `no_body_if_bereq_is_get_or_head`: Used to prevent a response body from being sent to the client if the request method is GET or HEAD.

You can confirm that these pragmas were added by navigating to your service’s **Service configuration > Show VCL.**

![](/_fern-img/d4c03d2b1c57357f34714b27abec9ee93af76e87ddaa9105f91e6d0969ee3276.webp)

### Contact HUMAN

After Fastly enables HUMAN support in your service, you need to contact the HUMAN team to receive the necessary VCL files and account information to complete your setup. To do so:

> **Note**
>
> If you’ve already received all this information, then you can skip this section.

1. [Contact us](/applications/human-customer-support) directly. Be sure to note that you are starting a Fastly VCL Enforcer configuration.
2. Ensure you receive all of the following:
   * The following **VCL files,** which you’ll use in [Upload and edit VCL files](#upload-and-edit-vcl-files):
     * `PX.vcl`
     * `PX_CONFIGS.vcl`
     * `PX_CUSTOM.vcl`
   * The following configuration values, which you’ll use while updating the [configs file settings](#configs-file-settings):
     * `px_remote_config_id`
     * `px_remote_config_auth_token`
   * The logger authentication token, which you’ll use in [Logging endpoint setup](#logging-endpoint-setup).

Once you receive these, you're ready to [Install the Enforcer](#install-the-enforcer).

## Install the Enforcer

Once you’ve enabled HUMAN support via Fastly and acquired all the necessary information from HUMAN, you’re ready to start installing the Enforcer.

1. Navigate to the Fastly dashboard and select the service you want to add the Enforcer to.
2. Select **Edit configuration > Clone.** Be sure to **note the version number you are editing.** This will be used as the `version_id` in later on in [Dictionary setup](#dictionary-setup).
3. Complete each of the following sections in order:
   1. [Dictionary setup](#dictionary-setup)
   2. [Upload and edit VCL files](#upload-and-edit-vcl-files)
   3. [MAIN file settings](#main-file-settings)
   4. [Logging endpoint setup](#logging-endpoint-setup)
   5. [Optional Fastly shielding functionality](#optional-fastly-shielding-functionality)
   6. [Optional WAF prefetch condition](#optional-waf-prefetch-condition)

### Dictionary setup

The HUMAN Fastly VCL Enforcer requires you create certain dictionaries to properly compile. To create them:

1. Navigate to **Service configuration > Data > Dictionaries** and select **Create** to make a new dictionary.
2. Create a Fastly dictionary named `px_enforcer_config_rdata`. You **do not** need to add any key values; HUMAN will populate the dictionary for you.

> **Note**
>
> The following steps **must** be completed via Fastly’s API. For your convenience, you may also download our provided [Postman Collection](https://www.postman.com/altimetry-pilot-59178614/human-fastly-vcl-enforcer-installation/collection/e9g1bya/fastly-vcl-enforcer-dictionaries?action=share\&creator=35980158).

3. Use Fastly’s **[Get an edge dictionary](https://www.fastly.com/documentation/reference/api/dictionaries/dictionary/#get-dictionary)** endpoint to retrieve the dictionary `id` for the `px_enforcer_config_rdata`, then **save it for later** on in the installation process. To make this call, you will need:
   * The `service_id`, which you can find at the top of your Fastly service.
   * The `version_id`, which is the version of the service you are **currently editing.**
   * Your Fastly API token.

```shell
curl -i "https://api.fastly.com/service/<service_id>/version/<version_id>/dictionary/px_enforcer_config_rdata" \
-H 'Fastly-Key: <fastly_api_token>' \
-H 'Accept: application/json'
```

4. Use Fastly's **[Create an edge dictionary endpoint](https://www.fastly.com/documentation/reference/api/dictionaries/dictionary/#create-dictionary)** to create a dictionary named `px_private`. Then, **save its `id`** for the next step. To make this call, you will need:
   * The `service_id`, which you can find at the top of your Fastly service.
   * The `version_id`, which is the version of the service you are **currently editing.**
   * Your Fastly API token.

```shell
curl -i -X POST https://api.fastly.com/service/<service_id>/version/<version_id>/dictionary \
-H 'Fastly-Key: <fastly_api_token>' \
-H "Content-Type: application/x-www-form-urlencoded" \
-H "Accept: application/json" \
-d 'name=px_private&write_only=true'
```

5. Use Fastly's **[Create an entry in edge dictionary](https://www.fastly.com/documentation/reference/api/dictionaries/dictionary-item/#create-dictionary-item)** endpoint to create an item key named `px_fastly_api_token` and with its item value as your Fastly API token.
   * The `service_id`, which you can find at the top of your Fastly service.
   * The `dictionary_id`, which is the `id` of the `px_private` dictionary you created in **Step 4.**
   * Your Fastly API token, which you’ll use to make the call **and** as the dictionary item value.

> **Note**
>
> Because `px_private` is a **private** Fastly dictionary, the item key and value pair may not appear in your Fastly service GUI, even after you’ve successfully created it via API call.

```shell
curl -i -X POST "https://api.fastly.com/service/<service_id>/dictionary/<dictionary_id>/item" \
-H 'Fastly-Key: <fastly_api_token>' \
-H "Content-Type: application/x-www-form-urlencoded" \
-H "Accept: application/json" \
-d 'item_key=px_fastly_api_token&item_value=<fastly_api_token>'
```

Next, you're ready to move on to [Upload and edit VCL files](#upload-and-edit-vcl-files).

### Upload and edit VCL files

The HUMAN Fastly VCL Enforcer consists of three custom VCL files that need to be uploaded to your service. These define the logic, configurations, and desired customizations for the VCL Enforcer. You can find a summary of all the files in the following table.

> **Note**
>
> If you don't have these files, see [Contact HUMAN](#contact-human).

| Provided file    | VCL file name | Explanation                                                                                                                                                                              |
| :--------------- | :------------ | :--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `PX.vcl`         | `PX`          | Contains all the internal HUMAN core logic. This file should **never** be modified.                                                                                                      |
| `PX_CONFIGS.vcl` | `PX_CONFIGS`  | Contains the enforcer configuration table and additional backend configs. This file **must** be modified. See [Configs file settings](#configs-file-settings) for more information.      |
| `PX_CUSTOM.vcl`  | `PX_CUSTOM`   | Contains the enforcer custom code, defined custom behavior and enforcer features. This file **may** be modified. See [Custom file settings](#custom-file-settings) for more information. |

Each file **must** be uploaded to your Fastly service. Follow the respective section to learn how to upload each file.

* [PX file settings](#px-file-settings)
* [Configs file settings](#configs-file-settings)
* [Custom file settings](#custom-file-settings)

#### PX file settings

To create the `PX` file in your Fastly service:

> **Warning**
>
> **Do not** make changes to the `PX.vcl` file

1. Navigate to **Service configuration > Custom VCL** and select **Upload a new VCL file.**
2. Enter `PX` for the **Name** of the file.
3. In **Config file,** select **Upload file** and select the provided `PX.vcl` file from HUMAN.
4. Select **Create.**

Your `PX` file should be created. Next, be sure to create a [configs file.](#configs-file-settings)

#### Configs file settings

To create the `PX_CONFIGS` file in your Fastly service:

1. Navigate to **Service configuration > Custom VCL** and select\*\* Upload a new VCL file.\*\*
2. Enter `PX_CONFIGS` for the **Name** of the file.
3. In **Config file,** select **Upload file** and select the provided `PX_CONFIGS.vcl` file from HUMAN.
4. Select **Create.**
5. If you are redirected to your VCL file list, select the **edit** button next to your `PX_CONFIGS` file.
6. In the **Edit VCL** field, set the following configurations shown below.

```shell
table px_configs {
    "px_app_id": "`<APP_ID>`", # see prerequisites
    "px_cookie_secret": "`<COOKIE_SECRET>`", # see prerequisites
    "px_auth_token": "`<AUTH_TOKEN>`", # see prerequisites
    "px_remote_config_id": "`<REMOTE_CONFIG_ID>`", # see contact human
    "px_remote_config_auth_token": "`<REMOTE_CONFIG_AUTH_TOKEN>`", # see contact human
    "px_enforcer_config_rdata_id": "`<REMOTE_CONFIG_DICTIONARY_ID>`" # see remote configuration setup
}
```

7. Additionally, update the `.host` value with your Application ID, as shown below.

```
backend PX_API {
    # ...
    .host = "sapi-<PX_APP_ID>.perimeterx.net"; # see prerequisites
    # ...
}
```

8. Select **Update.**

Your `PX_CONFIGS` file should be created. Next, see [Custom file settings.](#custom-file-settings)

#### Custom file settings

To create `PX_CUSTOM` in your Fastly service:

> **Note**
>
> You do not need to add any custom configurations for the Enforcer to function, but we recommend you upload the `px_custom.vcl` file regardless so you can return to make changes later.

1. Navigate to **Service configuration > Custom VCL** and select **Upload a new VCL file.**
2. Enter `PX_CUSTOM` for the **Name** of the file.
3. In **Config file,** select **Upload file** and select the provided `PX_CUSTOM.vcl` file from HUMAN.
4. Select **Create.**
5. If you are redirected to your VCL file list, select the **edit** button next to your `PX_CUSTOM` file.
6. In the **Edit VCL field**, customize your Enforcer configuration as desired. You can reference all available Fastly configurations in our [help article.](/applications/configuration-fastly-vcl-12)
7. Select **Update.**

Your `PX_CUSTOM` files should be created.

Now that you have uploaded all the files provided by HUMAN, you must now update the [MAIN file settings.](#main-file-settings)

### MAIN file settings

There is no single entry point for VCL code. Instead, Fastly exposes a number of different subroutines that function as "hooks" during the various stages of the [VCL request lifecycle.](https://www.fastly.com/documentation/guides/vcl/using/#the-vcl-request-lifecycle) These specific subroutines such as `vcl_recv` or `vcl_deliver` must be defined in a special custom VCL file known as the **MAIN file.** Typically, Fastly automatically creates a MAIN file when you create a new service. To integrate the HUMAN Enforcer into the MAIN file, we must invoke the appropriate HUMAN subroutine in every VCL hook subroutine.

| VCL hook subroutine | HUMAN Enforcer subroutine           |
| :------------------ | :---------------------------------- |
| `vcl_recv`          | `px_recv, px_recv_clustering_fixup` |
| `vcl_hash`          | -                                   |
| `vcl_hit`           | -                                   |
| `vcl_miss`          | `px_miss`                           |
| `vcl_pass`          | `px_pass`                           |
| `vcl_fetch`         | `px_fetch`                          |
| `vcl_deliver`       | `px_deliver`                        |
| `vcl_error`         | `px_error`                          |
| `vcl_log`           | `px_log`                            |

You will need to edit the existing MAIN file or create a new one with **all** the HUMAN Enforcer subroutines to your existing VCL hooks, which are listed below. While adding these subroutines, keep in mind that:

* The HUMAN subroutines should be called **as early as possible** in the defined hook. This is because the subroutines use request headers and [return statements](https://www.fastly.com/documentation/reference/vcl/statements/return/) to switch between different Fastly states and apply HUMAN enforcement logic only when necessary. Additionally, calling the enforcement flow in the very beginning helps avoid invoking business logic unnecessarily.
* The HUMAN subroutines should **always** be called **before** the Fastly macro.

> **Warning**
>
> The `px_recv_clustering_fixup` subroutine is the **only** exception for the above. `px_recv_clustering_fixup` should be called immediately **after** the `#FASTLY recv` macro rather than before.

To update your MAIN file:

1. Navigate to **Service configuration > Custom VCL.**
2. Edit your MAIN file or create a new one.
   1. If you **do** have an existing MAIN file, select **edit** button next to it.
   2. If you **don’t** have an existing MAIN file, copy the [available template from Fastly,](https://www.fastly.com/documentation/guides/vcl/using/#custom-vcl) select **Upload a new VCL file,** enter **MAIN** for its name, and paste the template you copied into **Edit VCL.**
3. In the **Edit VCL** field, update each VCL subroutine with the corresponding HUMAN subroutine from below.

> **Warning**
>
> If you implemented a Fastly **[Edge Rate Limit (ERL)](https://docs.fastly.com/products/edge-rate-limiting)** on the same Fastly Service you're deploying the Enforcer to, it can impact HUMAN's async activities.
>
> 1. If the ERL is called at the beginning of `vcl_recv`, a 429 error is thrown before the Enforcer initializes. This means that the Enforcer will not create any activities.
> 2. If the ERL is called at `vcl_pass` or `vcl_miss`, no `risk_api` activity will be sent and the traffic goes directly to `vcl_error` and `vcl_deliver`. Page requested activity will be generated.

**`RECV`**

```shell title="RECV"
sub vcl_recv {
    call px_recv;
    # ...
#FASTLY recv
    call px_recv_clustering_fixup;
    # ...
}
```

**`MISS`**

```shell title="MISS"
sub vcl_miss {
    call px_miss;
    # ...
#FASTLY miss
    # ...
}
```

**`PASS`**

```shell title="PASS"
sub vcl_pass {
    call px_pass;
    # ...
#FASTLY pass
    # ...
}
```

**`FETCH`**

```shell title="FETCH"
sub vcl_fetch {
    call px_fetch;
    # ...
#FASTLY fetch
    # In the event of a server-failure response from origin, retry once more
    if ((beresp.status == 500 || beresp.status == 503) && (req.restarts < 1 || is_px_server_failure()) && (req.method == "GET" || req.method == "HEAD")) {
      restart;
    }
    # ...
}
```

**`ERROR`**

```shell title="ERROR"
sub vcl_error {
    call px_error;
    # ...
#FASTLY error
    # ...
}
```

**`DELIVER`**

```shell title="DELIVER"
sub vcl_deliver {
    call px_deliver;
    # ...
#FASTLY deliver
    # ...
}
```

**`LOG`**

```shell title="LOG"
sub vcl_log {
    call px_log;
    # ...
#FASTLY log
    # ...
}
```

4. Update your existing MAIN file or create the one you just made.
   1. If you’re updating your **existing** MAIN file, select **Update.**
   2. If you’re creating a **new** MAIN file from Fastly’s template, select **Create**. Then, after you’re redirected to your VCL files list, select **Set as main** next to your new MAIN file.

Next, you're ready to move on to [Logging endpoint setup.](#logging-endpoint-setup)

### Logging endpoint setup

HUMAN uses your Fastly service’s **logging** to keep track of the Enforcer’s performance and activity. As part of the installation process, you will create three new HTTPS endpoints:

* **PX-Async-Activities:** Sends asynchronous activities, such as `page_requested` or `block`, to HUMAN's servers.
* **PX-Telemetry:** Enables the **telemetry** feature, which can send on-demand data about the Enforcer configuration to HUMAN.
* **HS-Log:** Sends Enforcer logs to HUMAN.

> **Note**
>
> **HS-Log** uses a **logger authentication token** that must be provided by HUMAN. If you do not have it, see [Contact HUMAN.](#contact-human)

To create the required logging endpoints:

1. Navigate to **Service configuration > Logging.**
2. On the **HTTPS** logging provider, select **Create endpoint.**
3. Create each endpoint with its corresponding fields as shown. If a Fastly field is not listed below, then you can use the default value or leave it blank.
   1. **PX-Async-Activities**
      * **Name:** PX-Async-Activities
      * **Placement:** None
      * **URL**: `https://collector-<px_app_id>.perimeterx.net/api/v1/collector/s2s`
      * **Maximum bytes**: 500000
      * Advanced options:
        * **Content type:** application/json
        * **JSON log entry format:** Array of JSON
   2. **PX-Telemetry**
      * **Name:** PX-Telemetry
      * **Placement:** None
      * **URL**: `https://collector-<px_app_id>.perimeterx.net/api/v2/risk/telemetry`
      * **Maximum Logs**: 1
      * Advanced options:
        * **Content type:** application/json
   3. **HS-Log**
      * **Name:** HS-Log
      * **Placement:** None
      * **URL**: `https://sapi-<APP_ID>.perimeterx.net/enforcer-logs/`
      * **Maximum Logs**: 1
      * Advanced options:
        * **Content type:** application/json
        * **Custom Header Name:** Authorization
        * **Custom Header Value:** Bearer \<LOGGER_AUTH_TOKEN>
        * **JSON log entry format:** Array of JSON
        * **Select a log line format:** Blank

Next, you can configure some optional settings:

* [Optional logging endpoints](#optional-logging-endpoints)
* [Optional Fastly shielding functionality](#optional-fastly-shielding-functionality)
* [Optional WAF prefetch condition](#optional-waf-prefetch-condition)

Otherwise, you can move on to [Wrap up.](#wrap-up)

### Optional logging endpoints

You can also add logging endpoints that receive messages from the Enforcer about the Fastly request flow. The Enforcer can send two types of logs depending on the configured `px_logger_severity`: **debug** and **error**.

To receive Enforcer logs:

1. Navigate to **Service configuration > Custom VCL.**
2. Select **Edit** next to your `PX_CONFIG` file.
3. Update `px_logger_severity` to the desired logging level.
4. Navigate to **Service configuration > Logging.**
5. On the **HTTPS** logging provider, select **create endpoint.**
6. Create a new endpoint named either `PX-Debug` or `PX-Error` depending on your desired endpoint.
7. Configure **where** you want the logs to go (e.g. URL). Other settings can stay as the default values.

> **Note**
>
> If you need to turn on Enforcer logs temporarily and you don't have an existing logging endpoint where you can easily view the logs, [Fastly's online log viewer](https://www.fastly.com/documentation/guides/integrations/logging/#troubleshooting) may provide a quick solution.

Next, depending on your Fastly service, you may need to configure the following:

* [Optional Fastly shielding functionality](#optional-fastly-shielding-functionality)
* [Optional WAF prefetch condition](#optional-waf-prefetch-condition)

Otherwise, you can move on to [Wrap up.](#wrap-up)

### Optional Fastly shielding functionality

The `px_shield` VCL snippet is required for **Fastly Shielding functionality** to stay enabled after a restart triggered by the Enforcer. You can learn more about Fastly’s shielding functionality with their [help article.](https://docs.fastly.com/en/guides/shielding)

To create `px_shield`:

1. Navigate to **Service configuration > VCL snippets.**
2. Select **Create a new VCL snippet.**
3. Create a snippet with the following settings:
   * **Name**: px_shield
   * **Type**: within subroutine - recv (vcl_recv)
   * **VCL**: `set var.fastly_req_do_shield = (req.restarts == 0 || (req.restarts == 1 && req.http.px-tmp:internal-flow == "1"));`
   * Advanced option
     * **Priority**: 1

Next, you may need to configure an [Optional WAF prefetch condition](#optional-waf-prefetch-condition). If you don’t, you can move on to [Wrap up.](#wrap-up)

### Optional WAF prefetch condition

If you are using Fastly WAF, we recommend adding condition to your Fastly service to address a potential issue that may arise from running WAF rules multiple times. This condition will effectively prevent the duplication of WAF activations and ensure a smoother operation of the integration for customers who have enabled Fastly WAF but have not implemented the WAF prefetch condition.

> **Note**
>
> This step is **not** applicable if using Fastly Next-Gen (Signal Sciences) WAF. If you are using Fastly Next-Gen (Signal Sciences) WAF, reach out to your HUMAN Solution Architect.

To add this condition to your service, you **must** use the [Fastly API](https://www.fastly.com/documentation/reference/api/vcl-services/condition/#create-condition). The condition should be made with the following settings:

* **Name**: PX-Waf-Prefetch-Condition
* **Type**: prefetch
* **Apply If**: `req.backend.is_origin && !req.http.bypasswaf`
* **Priority**: 10

```shell
curl -i -X POST "https://api.fastly.com/service/<service_id>/version/<version_id>/condition" \
-H "Fastly-Key: <fastly_api_token>" \
-H "Content-Type: application/x-www-form-urlencoded" \
-H "Accept: application/json" \
-d "name=PX-Waf-Prefetch-Condition&statement=req.backend.is_origin+%26%26+%21req.http.bypasswaf&type=PREFETCH&priority=10"
```

Next, you're ready for [Wrap up](#wrap-up).

## Wrap up

If you’ve completed your Enforcer installation, you **must** have the following in your Fastly service:

* In **Service configuration > Data > Dictionaries**, a dictionary named `px_enforcer_config_rdata`
* A **private dictionary**, `px_private`, with a key named `px_fastly_api_token`
* In **Service configuration > Custom VCL,** four VCL files:
  * `MAIN`, which **must** have the necessary HUMAN subroutines
  * `PX`, which **must not** have any changes to it
  * `PX_CONFIGS`, which **must** be updated with your unique values
  * `PX_CUSTOM`, which **may** have custom configurations as desired for your organization
* In **Service configuration > Logging,** three logging endpoints:
  * `PX-Async-Activities`
  * `PX-Telemetry`
  * `HS-Log`

You **may** also have:

* In **Service configuration > Logging,** two optional logging endpoints:
  * `PX-Debug`
  * `PX-Error`
* In **Service configuration > Snippets**, a snippet named **px_shield**
* In **Service configurations > Condition**, a condition named **PX-Waf-Prefetch-Condition**

If you have all of these items, then you’re ready to deploy your Fastly VCL Enforcer. From your Fastly **service**, select **Activate**. This will launch the Enforcer.

Once you finish installing, be sure to contact HUMAN to complete your Tuning process.