> 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 AWS Lambda@Edge Enforcer

If your organization uses **AWS CloudFront services,** you can use **HUMAN’s Lambda\@Edge Enforcer** to protect against malicious behavior. This Enforcer uses AWS Lambda functions to deploy the Enforcer on your content delivery network (CDN) and determine how traffic to your organization’s server should be handled.

You can learn how to install the 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 [AWS Lambda@Edge's primary installation article](/applications/aws-lambdaedge/v4/installation) for more information.

## Prerequisites

* An AWS account with appropriate permissions and access to the following (see AWS’ [help article](https://aws.amazon.com/blogs/networking-and-content-delivery/securing-and-accessing-secrets-from-lambdaedge-using-aws-secrets-manager/) for more information):
  * AWS CloudFront with an existing CloudFront distribution. See [AWS’ help article](https://docs.aws.amazon.com/AmazonCloudFront/latest/DeveloperGuide/distribution-web-creating-console.html) to learn how to create one.
  * AWS Lambda and permissions to deploy Lambda functions to CloudFront distributions
  * AWS CloudWatch
  * AWS IAM with permissions to create and modify IAM roles
* A **command-line interface (CLI).**
* A text editor.
* **GitHub CLI**. See [GitHub's repository](https://github.com/cli/cli#installation) to learn how to install it.
* **Node Version Manager (nvm)** installed on your device. See nvm's [GitHub repository](https://github.com/nvm-sh/nvm?tab=readme-ov-file#installing-and-updating) to learn how to install it.
* The latest version of **Node.js.** After installing nvm, enter `nvm install stable` in your CLI to install it.
* Your unique HUMAN information:
  * Your **Application ID.** You can find this under **Platform Settings > Applications > Overview** in the HUMAN 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 > Status & Settings > Server Token.**
  * Your **Risk Cookie Key.** You can find this under **Bot Defender > Policies > Policy Settings > Policy Information.** You may need to generate a new key if you do not already have one.

## Define the Lambda functions

The Lambda\@Edge Enforcer consists of three Lambda functions. Each function is integrated at a different event in an Amazon CloudFront distribution. They are:

> **Note**
>
> For more information on CloudFront events, see AWS’ [help article.](https://docs.aws.amazon.com/AmazonCloudFront/latest/DeveloperGuide/lambda-cloudfront-trigger-events.html)

* **HumanEnforcer Lambda (required):** Triggered by the **viewer request** event. You **must** create this Lambda function to properly install the Enforcer.
* **HumanActivities Lambda (optional):** Triggered by the **origin response.** You should only integrate this Lambda if you have enabled features or products that require response data.
* **HumanFirstParty Lambda (optional):** Triggered by the **origin request.** This Lambda will only be used for first-party requests from HUMAN, and it will not monitor typical website traffic.

The process for defining your Lambda functions is different depending on if you have an existing Lambda project or not.

* If you **do not** have an existing Lambda project, see [Define with the HUMAN template.](https://docs.humansecurity.com/applications-and-accounts/docs/manually-install-the-aws-lambdaedge-enforcer#define-with-the-human-template)
* If you **do** have an existing Lambda project, see [Define with an existing project.](https://docs.humansecurity.com/applications-and-accounts/docs/manually-install-the-aws-lambdaedge-enforcer#define-with-an-existing-project)

### Define with the HUMAN template

If you **do not** have an existing AWS project, then you can use HUMAN's premade templates to quickly create and install the AWS Lambda\@Edge Enforcer. This Enforcer is publicly available from our [GitHub repository.](https://github.com/PerimeterX/aws-lambda-edge-template)

1. In your CLI, enter `git clone https://github.com/PerimeterX/aws-lambda-edge-template`.
2. Enter `cd aws-lambda-edge-template`.
3. Enter `npm install`. This installs the necessary dependencies to use the Enforcer template.
4. In your preferred text editor, open `basic_example/src/custom/config.json` and update the `px_app_id`, `px_auth_token`, and `px_cookie_secret` fields with your **Application ID, Server Token,** and **Risk Cookie Key** respectively.

> **Note**
>
> These are the **minimum** required settings to configure the Enforcer. To customize it further, see our [custom configurations.](/applications/configuration-aws-lambda-edge) We recommend adding your configurations **before** uploading any Lambda function to your CloudFront distribution for the first time.
>
> You can store sensitive information, such as your **Server Token** and **Risk Cookie Key,** in the **AWS Secrets Manager** rather than inserting them directly into your configuration. See AWS’ [help article](https://aws.amazon.com/blogs/networking-and-content-delivery/securing-and-accessing-secrets-from-lambdaedge-using-aws-secrets-manager/) to learn how to do so.

5. Save `config.json`.
6. In your CLI, enter `npm run zip` to bundle your Lambda functions into ZIP files. This should create `HumanActivities.zip`, `HumanEnforcer.zip`, and `HumanFirstParty.zip`.

Next, see the steps in [Deploy the Enforcer](/applications/installation-aws-lambda-edge#deploy-the-enforcer) to complete your setup.

### Define with an existing project

If you already have a Lambda project that you want to integrate the HUMAN Enforcer with, then you can follow the steps below.

> **Note**
>
> Each Lambda function requires slightly different steps to configure and deploy to CloudFront. Be sure to follow the right section to complete each one.

The **HumanEnforcer Lambda** is **required.**

To get started:

1. Navigate to the directory of your Lambda project that contains the `package.json` file. Typically, this is the root directory of your project.
2. Enter `npm i --save @humansecurity/aws-lambda-edge-enforcer`. This will update your `package.json` dependencies with the latest HUMAN AWS Lambda\@Edge Enforcer package.
3. Create a `config.json` file. We recommend doing this if you are creating multiple Lambda functions. If you plan to define custom functions as part of your configuration, you may want to modify this file to be a JavaScript (i.e., `config.js`) or TypeScript file (i.e., `config.ts`) rather than a JSON file.

Then, follow the appropriate section for each Lambda function:

* [Define the HumanEnforcer Lambda](https://docs.humansecurity.com/applications-and-accounts/docs/manually-install-the-aws-lambdaedge-enforcer#define-the-humanenforcer-lambda) (required)
* [Define the HumanActivities Lambda](https://docs.humansecurity.com/applications-and-accounts/docs/manually-install-the-aws-lambdaedge-enforcer#define-the-humanactivities-lambda)
* [Define the HumanFirstParty Lambda](https://docs.humansecurity.com/applications-and-accounts/docs/manually-install-the-aws-lambdaedge-enforcer#define-the-humanfirstparty-lambda)

#### Define the HumanEnforcer Lambda

The HumanEnforcer Lambda is the primary Lambda that determines the behavior of traffic activity in your CloudFront distribution. This Lambda is **required** so that the AWS Lambda\@Edge Enforcer can function.

1. In your `config.json` file, insert the following code and update the `APP_ID`, `AUTH_TOKEN`, and `COOKIE_SECRET` fields with your **Application ID, Server Token,** and **Risk Cookie Key** respectively.

> **Note**
>
> We recommend using the **AWS Secrets Manager** to securely store sensitive tokens such as your **Server Token** and **Risk Cookie Key** in the **AWS Secrets Manager** rather than inserting them directly into your configuration. See AWS’ [help article](https://aws.amazon.com/blogs/networking-and-content-delivery/securing-and-accessing-secrets-from-lambdaedge-using-aws-secrets-manager/) to learn how to do so.

If you also want to add any custom configurations, we recommend doing so in this step **before** uploading any Lambda function to AWS CloudFront for the first time. You can review our available configurations with our [help article.](https://docs.humansecurity.com/applications-and-accounts/docs/configuration-aws-lambda-edge)

```json
{
    "px_app_id": "<APP_ID>",
    "px_auth_token": "<AUTH_TOKEN>",
    "px_cookie_secret": "<COOKIE_SECRET>"
}
```

2. In the file with your existing Lambda’s source code, add the appropriate code from below depending on if you have **existing handler logic.**

> **Note**
>
> AWS Lambda considers it best practice to use **async/await syntax,** but a callback-based alternative is available as well if you use it.

**`Without existing handler logic`**

```typescript title="Without existing handler logic"
// index.ts
import { createHumanEnforceHandler } from '@humansecurity/aws-lambda-edge-enforcer';
import config from "./config.json"

// create and export the handler
export const handler = createHumanEnforceHandler(config);
```

**`With existing handler logic`**

```typescript title="With existing handler logic"
// index.ts
import { CloudFrontRequest, CloudFrontRequestEvent, CloudFrontResponseResult, Context } from 'aws-lambda';
import { HumanSecurityEnforcer } from '@humansecurity/aws-lambda-edge-enforcer';
import config from "./config.json"

// initialize the enforcer
const enforcer = HumanSecurityEnforcer.initialize(config);

// define a handler
export async function handler(
    event: CloudFrontRequestEvent,
    context: Context
): Promise<CloudFrontRequest | CloudFrontResponseResult> {
    // extract the request from the event
    const request = event.Records[0].cf.request;

    // call enforce() and await the response
    // recommend calling before any existing logic
    // request is a required argument, context is optional
    const result = await enforcer.enforce(request, context);

    // return the result if it exists
    if (result) {
        return result;
    }

    // execute your existing logic on the request here

    // eventually return the request
    return request;
};
```

**`Callback-based logic`**

```typescript title="Callback-based logic"
// index.ts
import { CloudFrontRequest, CloudFrontRequestEvent, CloudFrontResponseResult, Context } from 'aws-lambda';
import { HumanSecurityEnforcer } from '@humansecurity/aws-lambda-edge-enforcer';
import config from "./config.json"

// initialize the enforcer
const enforcer = HumanSecurityEnforcer.initialize(config);

// define a handler
export function handler(event, context, callback) {
    // improves performance by not blocking critical path when sending enforcer async activities
    // with this flag set to false, async activities are sent on subsequent Lambda invocations
    context.callbackWaitsForEmptyEventLoop = false;

    // extract the request from the event
    const request = event.Records[0].cf.request;

    // call enforce() and call then() on the returned Promise
    // recommend calling before any existing logic
    // request is a required argument, context is optional
    enforcer.enforce(request, context).then((result) => {
        if (result) {
            // invoke the callback with the result if it exists
            callback(null, result);
        } else {
            // execute your existing logic on the request here

            // eventually invoke the callback with the request
            callback(null, request);
        }
    });
};
```

3. If you want to deploy other Lambdas with the Enforcer, complete the setup for each by following the steps in either [Define the HumanActivities Lambda](#define-the-humanactivities-lambda) or [Define the HumanFirstParty Lambda.](#define-the-humanfirstparty-lambda)
4. Save `config.json`.
5. Bundle your Lambda function into a JavaScript file. For example, if you are bundling a function in a TypeScript file named `index.ts` into the `dist` directory, you would run: `esbuild ./index.ts --bundle --minify --platform=node --target=es2022 --outfile=dist/index.js`.
6. Zip your bundled function.

Once you’ve zipped your function, see the steps in [Deploy the Enforcer](/applications/installation-aws-lambda-edge#deploy-the-enforcer) to complete your setup.

#### Define the HumanActivities Lambda

You only need to configure the HumanActivities Lambda if you want to send the custom HUMAN configuration `additional_s2s_activity` to the **origin.** This lets HUMAN analyze data related to the response in addition to the request.

1. In your `config.json` file, insert the following code and update the `APP_ID`, `AUTH_TOKEN`, and `COOKIE_SECRET` fields with your **Application ID, Server Token,** and **Risk Cookie Key** respectively.

> **Note**
>
> We recommend defining this using the same configuration you used for the [HumanEnforcer Lambda](/applications/aws-lambdaedge/v4/installation#define-the-humanenforce-lambda).

```json
{
    "px_app_id": "<APP_ID>",
    "px_auth_token": "<AUTH_TOKEN>",
    "px_cookie_secret": "<COOKIE_SECRET>"
}
```

2. In the file with your existing Lambda’s source code, add the appropriate code from below depending on if you have **existing handler logic.**

**`Without existing handler logic`**

```typescript title="Without existing handler logic"
// index.ts
import { createHumanActivitiesHandler } from '@humansecurity/aws-lambda-edge-enforcer';
import config from "./config.json"

// create and export the handler
export const handler = createHumanActivitiesHandler(config);
```

**`With existing handler logic`**

```typescript title="With existing handler logic"
// index.ts
import { CloudFrontResponseEvent, CloudFrontResponseResult, Context } from 'aws-lambda';
import { HumanSecurityPostEnforcer } from '@humansecurity/aws-lambda-edge-enforcer';
import config from "./config.json"

// initialize the postEnforcer
const postEnforcer = HumanSecurityPostEnforcer.initialize(config);

// define a handler
export async function handler(
    event: CloudFrontResponseEvent,
    context: Context
): Promise<CloudFrontResponseResult> {
    // extract the request and response from the event
    const request = event.Records[0].cf.request;
    const response = event.Records[0].cf.response;

    // execute your custom logic on the response here

    // call and await the postEnforce() function
    await postEnforcer.postEnforce(request, response);

    // return the response
    return response;
};
```

3. If you want to deploy other Lambdas with the Enforcer, complete the setup for each by following the steps in either [Deploy the HumanEnforcer Lambda](/applications/aws-lambdaedge/v4/installation#deploy-the-humanenforce-lambda) or [Deploy the HumanFirstParty Lambda.](/applications/aws-lambdaedge/v4/installation#deploy-the-humanfirstparty-lambda) Otherwise, continue to the next step.
4. Save `config.json`.
5. Bundle your Lambda function into a JavaScript file. For example, if you are bundling a function in a TypeScript file named `index.ts` into the `dist` directory, you would run: `esbuild ./index.ts --bundle --minify --platform=node --target=es2022 --outfile=dist/index.js`.
6. Zip your files.

Once you’ve zipped your function, see the steps in [Deploy the Enforcer](/applications/installation-aws-lambda-edge#deploy-the-enforcer) to complete your setup.

#### Define the HumanFirstParty Lambda

You only need to configure the HumanFirstParty Lambda if you want to support **first-party requests.** You can learn more about these requests with our [help article.](/applications/generic-cdn-first-party-config)

1. In your `config.json` file, insert the following code and update the `APP_ID` field with your **Application ID** and add relevant first-party custom configurations you want to include to the definition.

> **Note**
>
> We recommend defining this using the same configuration you used for the [HumanEnforcer Lambda](/applications/aws-lambdaedge/v4/installation#define-the-humanenforce-lambda).

```json
{
    "px_app_id": "<APP_ID>",
    "px_auth_token": "<AUTH_TOKEN>",
    "px_cookie_secret": "<COOKIE_SECRET>"
}
```

2. In the file with your existing Lambda’s source code, add the following code:

```typescript
// index.ts
import { createHumanFirstPartyHandler } from '@humansecurity/aws-lambda-edge-enforcer';
import config from "./config.json"

export const handler = createHumanFirstPartyHandler(config);
```

3. If you want to deploy other Lambdas with the Enforcer, complete the setup for each by following the steps in either [Deploy the HumanEnforcer Lambda](/applications/aws-lambdaedge/v4/installation#deploy-the-humanenforce-lambda) or [Deploy the HumanActivities Lambda.](/applications/aws-lambdaedge/v4/installation#deploy-the-humanactivities-lambda) Otherwise, continue to the next step.
4. Save `config.json`.
5. Bundle your Lambda function into a JavaScript file. For example, if you are bundling a function in a TypeScript file named `index.ts` into the `dist` directory, you would run: `esbuild ./index.ts --bundle --minify --platform=node --target=es2022 --outfile=dist/index.js`.
6. Zip your files.

Once you’ve zipped your function, see the steps in [Deploy the Enforcer](/applications/installation-aws-lambda-edge#deploy-the-enforcer) to complete your setup.

## Deploy the Enforcer

Now that you have your Lambda functions ready, you must upload them to AWS CloudFront and deploy them. The steps to upload each type of Lambda are different, so be sure to follow the correct instructions for the Lambda you’re uploading.

> **Note**
>
> Ensure you are on US East (N. Viriginia), us-east-1 when creating Lambda functions. Lambda\@Edge functions can only be deployed from us-east-1. For more information, see [AWS’ help article.](https://docs.aws.amazon.com/AmazonCloudFront/latest/DeveloperGuide/lambda-at-edge-function-restrictions.html#lambda-at-edge-restrictions-region)

* [Upload the HumanEnforcer Lambda (required)](#upload-the-humanenforcer-lambda-required)
* [Upload the HumanActivities Lambda](#upload-the-humanactivities-lambda)
* [Upload the HumanFirstParty Lambda](#upload-the-humanfirstparty-lambda)
* [Enable CloudWatch logs (recommended)](#enable-cloudwatch-logs-recommended)

### Upload the HumanEnforcer Lambda (required)

Complete the following steps to upload the HumanEnforcer Lambda.

1. Navigate to **Lambda > Functions.**
2. Select **Create function** to make a new Lambda function.
3. Select the option to **Author from scratch.**
4. Complete the fields to create a new function. You can leave most of the fields with their **default values,** but be sure to **update the following:**
   * **Function name:** Enter the name for your function.
   * **Runtime:** Select at least Node.js 18.x or higher.
   * **Permissions > Change default execution role > Execution role:** Choose the appropriate role defined by your Lambda permissions and fill in the fields that appear if necessary. The role is determined by your organization’s AWS policy.
     * If your organization already has a role with the appropriate permissions, select **Use an existing role.**
     * If your organization does not have an appropriate role, create a new one with one of the available options.
5. Select **Create function** to finish making your function.
6. From your **Lambda > Functions** table, select the function you just created.
7. In the **Code source** section, select **Upload from** and choose **.zip file.**
8. Select the Lambda function ZIP file.
9. Select **Save.**
10. Select **Actions > Publish new version.**
11. Copy the **Function ARN.**
12. Navigate to **CloudFront > Distributions.**
13. Select a **Distribution ID > Behaviors.**
14. If you already have a behavior that uses the **Default (\*)** path pattern, select it. Otherwise, select **Create behavior.**
15. Complete the following fields:
    * **Path Pattern:** Default (\*)
    * **Cache policy and origin request policy (recommended):** Select an **origin request policy** to ensure you do not remove important headers. If one does not exist, see AWS’ [help article](https://docs.aws.amazon.com/AmazonCloudFront/latest/DeveloperGuide/origin-request-create-origin-request-policy.html) to create one. Our recommendations are:
      * [**AllViewerExceptHostHeader:**](https://docs.aws.amazon.com/AmazonCloudFront/latest/DeveloperGuide/using-managed-origin-request-policies.html#managed-origin-request-policy-all-viewer-except-host-header) We recommend using this policy, especially if you are also uploading the **HumanFirstParty Lambda.**
      * [AllViewer](https://docs.aws.amazon.com/AmazonCloudFront/latest/DeveloperGuide/using-managed-origin-request-policies.html#managed-origin-request-policy-all-viewer)
      * [AllViewerAndCloudFrontHeaders-2022-06](https://docs.aws.amazon.com/AmazonCloudFront/latest/DeveloperGuide/using-managed-origin-request-policies.html#managed-origin-request-policy-all-viewer-and-cloudfront)
    * **Viewer request** event:
      * Select **Lambda\@Edge** for the **function type.**
      * Paste the **Function ARN** from **Step 11** in the field that appears.
16. Select **Save changes.**

You have successfully integrated the HUMAN AWS Lambda\@Edge Enforcer with your CloudFront distribution. Make sure to reach out to our support team to complete your tuning process.

### Upload the HumanActivities Lambda

Complete the following steps to upload the HumanActivities Lambda.

1. Navigate to **Lambda > Functions.**
2. Select **Create function** to make a new Lambda function.
3. Select the option to **Author from scratch.**
4. Complete the fields to create a new function. You can leave most of the fields with their **default values,** but be sure to **update the following:**
   * **Function name:** Enter the name for your function.
   * **Runtime:** Select at least Node.js 18.x or higher.
   * **Permissions > Change default execution role > Execution role:** Choose the appropriate role defined by your Lambda permissions and fill in the fields that appear if necessary. The role is determined by your organization’s AWS policy.
     * If your organization already has a role with the appropriate permissions, select **Use an existing role.**
     * If your organization does not have an appropriate role, create a new one with one of the available options.
5. Select **Create function** to finish making your function.
6. From your **Lambda > Functions** table, select the function you just created.
7. In the **Code source** section, select **Upload from** and choose **.zip file.**
8. Select the Lambda function ZIP file.
9. Select **Save.**
10. Select **Actions > Publish new version.**
11. Copy the **Function ARN.**
12. Navigate to **CloudFront > Distributions.**
13. Select a **Distribution ID > Behaviors.**
14. If you already have a behavior that uses the **Default (\*)** path pattern, select it. Otherwise, select **Create behavior.**
15. Complete the following fields:
    * **Path Pattern:** Default (\*)
    * **Origin response:**
      * Select **Lambda\@Edge** for the **function type.**
      * Paste the **Function ARN** from **Step 11** in the field that appears.
16. Select **Save changes.**

Make sure you also upload the [HumanEnforcer Lambda.](#upload-the-humanenforcer-lambda-required) Once you do, you have successfully integrated the HUMAN AWS Lambda\@Edge Enforcer with your CloudFront distribution. Make sure to reach out to our support team to complete your tuning process.

### Upload the HumanFirstParty Lambda

Complete the following steps to upload the HumanFirstParty Lambda.

1. Navigate to **Lambda > Functions.**
2. Select **Create function** to make a new Lambda function.
3. Select the option to **Author from scratch.**
4. Complete the fields to create a new function. You can leave most of the fields with their **default values,** but be sure to **update the following:**
   * **Function name:** Enter the name for your function.
   * **Runtime:** Select at least Node.js 18.x or higher.
   * **Permissions > Change default execution role > Execution role:** Choose the appropriate role defined by your Lambda permissions and fill in the fields that appear if necessary. The role is determined by your organization’s AWS policy.
     * If your organization already has a role with the appropriate permissions, select **Use an existing role.**
     * If your organization does not have an appropriate role, create a new one with one of the available options.
5. Select **Create function** to finish making your function.
6. From your **Lambda > Functions** table, select the function you just created.
7. In the **Code source** section, select **Upload from** and choose **.zip file.**
8. Select the Lambda function ZIP file.
9. Select **Save.**
10. Select **Actions > Publish new version.**
11. Copy the **Function ARN.**
12. Navigate to **CloudFront > Policies > Cache** and select **Create cache policy.**
13. Create a cache policy with the following settings:
    * **Minimum TTL:** 0
    * **Maximum TTL:** 10
    * **Default TTL:** 5
    * **Headers:** Include the following headers
      * Host
      * User-agent
    * **Query strings:** All
    * **Cookies:** Including the following cookies
      * \*\_px\*
      * px\*\*
14. Select **Create.**

> **Warning**
>
> If the Enforcer was configured to use custom first party endpoints, you must create additional cache behaviors for the custom first party path patterns. Otherwise, requests using the custom paths will not be handled properly.

15. Navigate to **CloudFront > Distributions.**
16. Select a **Distribution ID > Behaviors.**
17. Select **Create behavior.**
18. Complete the following fields:
    * **Path Pattern:** `/<APP_ID_without_PX>/*`. For example, for an ID that is PX123456, the path pattern should be `/123456/*`.
    * **Viewer protocol policy:** HTTP and HTTPS
    * **Allowed HTTP methods:** GET, HEAD, OPTIONS, PUT, POST, PATCH, DELETE
    * **Cache policy:** Select the cache policy you created in **Step 14.**
    * **Origin request policy:** AllViewerExceptHostHeader. You should have created this origin request policy while completing the steps in [Upload the HumanEnforcer Lambda (required)](/applications/aws-lambdaedge/v4/installation#upload-the-humanenforcer-lambda-required).
    * **Origin request:**
      * Select **Lambda\@Edge** for the **function type.**
      * Paste the **Function ARN** from **Step 11** in the field that appears.
19. Select **Save changes.**

Make sure you also upload the [HumanEnforcer Lambda.](#upload-the-humanenforcer-lambda-required) Once you do, you have successfully integrated the HUMAN AWS Lambda\@Edge Enforcer with your CloudFront distribution. Make sure to reach out to our support team to complete your tuning process.

### Enable CloudWatch logs (recommended)

We recommend creating an IAM role for each Lambda you upload. This lets the function create log groups and log streams in CloudWatch. When you deploy a Lambda\@Edge function, it distributes across all edge cache locations, and all logs from the Lambda related to those regions will appear in the CloudWatch logs of their respective edge cache areas. For example, if a user accesses the us-east-1 region, the corresponding logs will be found in us-east-1.

```typescript
{  
"Version": "2012-10-17",  
"Statement": \[  
    {  
        "Effect": "Allow",  
        "Action": "logs:CreateLogGroup",  
        "Resource": "arn:aws:logs:_:_:_"  
    },  
    {  
        "Effect": "Allow",  
        "Action": [  
            "logs:CreateLogStream",  
            "logs:PutLogEvents"  
        ],  
        "Resource": \[  
            "arn:aws:logs:_:_:log-group:_:\*"  
        ]  
    }  
  ]  
}
```

## Deploy the Enforcer using AWS CloudFromation

AWS CloudFormation is a service that enables users to model and manage infrastructure resources in an automated and secure manner.\
Using CloudFormation, developers can define and provision AWS infrastructure resources using a JSON- or YAML-formatted infrastructure as code template.

### Who can't use this feature?

* If your AWS resources are managed by other IaC platforms like Pulumi, Terraform, etc.
* If you already have a CloudFront distribution in your AWS account and you want to integrate the Enforcer with it.

If one of these applies to you, you can follow the instructions in [Deploy the Enforcer.](#deploy-the-enforcer)

### Prerequisites:

* Complete the instructions in the `install the enforcer` section and make sure you have the lambda zip files.
* AWS CLI installed and configured.
* AWS S3 bucket to store the lambda zip files.

> **Note**
>
> The following steps are for deploying the HUMAN  Enforcer to a new CloudFront distribution. The deployment includes the HumanEnforcer lambda and the HumanFirstParty lambda, but the HumanActivities lambda is not included. To add it, see [How to add HumanActivitiesLambda](#how-to-add-humanactivitieslambda) before deploying the CloudFormation stack.

1. Store the lambda zip files in the S3 bucket using the following command:
   ```bash
   aws s3 cp HumanEnforcer.zip s3://<bucket-name>/HumanEnforcer.zip
   aws s3 cp HumanActivities.zip s3://<bucket-name>/HumanActivities.zip
   aws s3 cp HumanFirstParty.zip s3://<bucket-name>/HumanFirstParty.zip
   ```
2. Navigate to the `deploy` directory.
   ```bash
   cd deploy
   ```
3. Edit the `cfm_deploy.yaml` file and replace the placeholders with the relevant values:

* `DomainName: "<ORIGIN_DOMAIN_URL>" `
* **Example:** `- DomainName: "example.com"`

```yaml
    CloudFrontDistribution:
    Type: "AWS::CloudFront::Distribution"
    Properties:
      DistributionConfig:
        Enabled: true
        Origins:
          - DomainName: "<ORIGIN_DOMAIN_URL>"
            Id: "ExampleOrigin"
            CustomOriginConfig:
              HTTPPort: 80
              HTTPSPort: 443
              OriginProtocolPolicy: "https-only"
```

* PathPattern: `"<PX_APP_ID_SUFFIX>/*"`
* **Example**: for PX\_APP\_ID: `pxapp12345` the `PX_APP_ID_SUFFIX` is `app12345` (Remove the PX prefix from the app\_id)

```yaml
        CacheBehaviors:
          - PathPattern: "<PX_APP_ID_SUFFIX>/*"
            AllowedMethods:
                - "GET"
                - "HEAD"
                - "OPTIONS"
                - "PUT"
                - "POST"
                - "PATCH"
                - "DELETE"
```

Example:

```yaml
        CacheBehaviors:
          - PathPattern: "pxapp12345/*"
            AllowedMethods:
                - "GET"
                - "HEAD"
                - "OPTIONS"
                - "PUT"
                - "POST"
                - "PATCH"
                - "DELETE"
```

4. Deploy the CloudFormation stack using the following command (**NOTE: replace the placeholders with the relevant values - `<stack-name>` and `<bucket-name>`**):
   ```bash
   aws cloudformation deploy \                                    
   --stack-name <stack-name> \
   --template-file cfm_deploy.yaml \
   --capabilities CAPABILITY_IAM \
   --parameter-overrides \
   HumanLambdaCodeBucket=<bucket-name> \
   EnforcerLambdaCodePath=HumanEnforcer.zip \
   FirstPartyLambdaCodePath=HumanFirstParty.zip
   ```
5. After the stack is created, you can find the CloudFront distribution URL in the CloudFormation stack outputs (or in the AWS UI).

## Add HumanActivitiesLambda

HumanActivitiesLambda is an optional additional lambda that runs on the origin response and can be used to send additional activities that require response information to the HUMAN Security API. This Lambda is in charge of generating the HUMAN Security PXHD cookie and needs to be deployed in case you're using advanced features such as Credential Intelligence or GraphQL protection.

To add the HumanActivitiesLambda to the CloudFormation stack, you must adjust your `cfm_deploy.yaml` file to include the HumanActivitiesLambda before deployment.

1. Create the Activities Lambda by adding the following resource to your deployment yaml (after `EnforcerExecutionRole`, at line 65):

```yaml
  HumanActivitiesLambda:
    Type: "AWS::Lambda::Function"
    Properties:
      FunctionName: "human-security-activities-lambda"
      Handler: "index.handler"
      Role: !GetAtt EnforcerExecutionRole.Arn
      Runtime: "nodejs20.x"
      Code:
        S3Bucket: !Ref HumanLambdaCodeBucket
        S3Key: !Ref ActivitiesLambdaCodePath

  HumanActivitiesLambdaFunctionVersion:
    Type: "AWS::Lambda::Version"
    Properties:
      FunctionName: !Ref HumanActivitiesLambda
```

2. Add to `LambdaFunctionAssociations` an `origin-response` EventType, with the following association: `LambdaFunctionARN: !Ref HumanActivitiesLambdaFunctionVersion`. For example:

```yaml
            LambdaFunctionAssociations:
              - EventType: "viewer-request"
                LambdaFunctionARN: !Ref HumanEnforcerLambdaFunctionVersion
              - EventType: "origin-response"
                LambdaFunctionARN: !Ref HumanActivitiesLambdaFunctionVersion
```

3. Add the `ActivitiesLambdaCodePath` variable at the end of the yaml file. For example:

```yaml
    ActivitiesLambdaCodePath:
    Type: String
    Description: "S3 path for the Activities Lambda code zip file."
```

4. Run the deployment command using the 3 lambdas:

```bash
aws cloudformation deploy \                                    
--stack-name <stack-name> \
--template-file cfm_deploy.yaml \
--capabilities CAPABILITY_IAM \
--parameter-overrides \
HumanLambdaCodeBucket=<bucket-name> \
EnforcerLambdaCodePath=HumanEnforcer.zip \
ActivitiesLambdaCodePath=HumanActivities.zip \
FirstPartyLambdaCodePath=HumanFirstParty.zip
```