> 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.

# Configuration

## Overview

The HUMAN enforcer can be configured within the JavaScript code via the configuration object.

## HSConfig

An object of configuration values that dictate the behavior of the Enforcer. This object is needed when creating a new Enforcer instance.

Required values:

* px\_app\_id
* px\_auth\_token
* px\_cookie\_secret

> **Storing Secrets and Tokens**
>
> It's safest to store tokens and secrets in the [AWS Secrets Manager](https://docs.aws.amazon.com/secretsmanager/latest/userguide/retrieving-secrets_lambda.html) or as [environment variables](https://docs.aws.amazon.com/lambda/latest/dg/configuration-envvars.html#configuration-envvars-example) rather than hardcoding them into the JavaScript code.

### px\_app\_id

The application ID. Required to initialize the Enforcer.

```ts
const config: HSConfig = {
    // ...
    px_app_id: '<APP_ID>',
    // ...
}
```

### px\_auth\_token

The token used for authorization with the HUMAN backend. Required to initialize the Enforcer.

```ts
const config: HSConfig = {
    // ...
    px_auth_token: '<AUTH_TOKEN>',
    // ...
}
```

### px\_cookie\_secret

The secret used to encrypt and decrypt the risk cookie. Required to initialize the Enforcer.

```ts
const config: HSConfig = {
    // ...
    px_cookie_secret: '<COOKIE_SECRET>',
    // ...
}
```

### px\_module\_enabled

This boolean serves as an on/off switch for the entire module, providing a way to enable and disable all Enforcer capabilities quickly and easily.

**Default**: `true`

```ts
const config: HSConfig = {
    // ...
    px_module_enabled: false,
    // ...
}
```

### px\_module\_mode

This feature controls the behavior of the enforcer by changing how it executes certain parts of the workflow. Most notably, different modes allow for analysis and fine-tuning of the enforcer behavior without serving block pages that affect end users.

Possible values:

* `"monitor"` - the enforcer will perform all functions without returning block responses
* `"active_blocking"` - the enforcer will return block responses when needed

**Default**: `"monitor"`

```ts
const config: HSConfig = {
    // ...
    px_module_mode: 'active_blocking',
    // ...
}
```

### px\_logger\_severity

The verbosity of the logs generated by the enforcer.

Possible values:

* `"none"` - No logs will be generated
* `"error"` - Sparse logs will be generated only when errors occur
* `"debug"` - Detailed logs will always be generated (not advisable for production environments)

**Default**: `"error"`

```ts
const config: HSConfig = {
    // ...
    px_logger_severity: 'debug',
    // ...
}
```

### px\_s2s\_timeout

The maximum time in milliseconds to wait for the risk API request. If this timeout is reached, the original request will be allowed to pass (fail open).

**Default**: `1000`

```ts
const config: HSConfig = {
    // ...
    px_s2s_timeout: 2000,
    // ...
}
```

### px\_ip\_headers

By default, the IP is taken from `event.requestContext.identity.sourceIp` property. However, if this value is inaccurate, the enforcer can extract the IP from the headers configured here. The headers are traversed in the order they are listed. The first header value that exists will be used as the client IP.

**Default**: `[]`

```ts
const config: HSConfig = {
    // ...
    px_ip_headers: ['true-ip', 'true-client-ip'],
    // ...
}
```

### px\_advanced\_blocking\_response\_enabled

In specific cases (e.g., XHR post requests), a full captcha page render might not be an option. In such cases the advanced blocking response returns a JSON object containing all the information needed to render a customized captcha challenge implementation - be it a popup modal, a section on the page, etc. This allows for flexibility and customizability in terms\
of how the captcha pages are displayed.

**Default**: `true`

```ts
const config: HSConfig = {
    // ...
    px_advanced_blocking_response_enabled: false,
    // ...
}
```

### px\_first\_party\_enabled

To prevent suspicious or unwanted behavior on the client side, some browsers or extensions (e.g., adblockers) may deny the frontend JavaScript code from making requests to other domains. This prevents the HUMAN sensor from making requests to the HUMAN backends, which greatly limits HUMAN's detection capabilities. To avoid this problem, first party enables the enforcer to be used as a proxy for HUMAN servers, and to serve content to the browser from a first party endpoint (i.e., an endpoint on the customer’s domain).

**Default**: `true`

```ts
const config: HSConfig = {
    // ...
    px_first_party_enabled: false,
    // ...
}
```

### px\_custom\_first\_party\_prefix

By default, first party endpoints always begin with the application ID without the initial "PX". For example, if the application ID is `PX12345678`, then all first party routes will take the form `/12345678/*`. This configuration sets a custom prefix for first party routes to use in addition to the default prefix. When configured, the enforcer will respond to first party requests with endpoints matching the patterns `/<px_custom_first_party_prefix>/init.js`, `/<px_custom_first_party_prefix>/xhr/*`, and `/<px_custom_first_party_prefix>/captcha/*`.

> **Note**
>
> Since API Gateway includes the stage name in the URL paths to resources, this value should be configured to wherever the HUMAN first party resources are routed in the API Gateway. Based on the installation instructions, this value should be configured to `"/<stage_name>/<app_id_without_px>"` (e.g., if the stage name is `v1` and the application ID is `PX12345678`, then this value should be `"/v1/12345678"`).

**Default**: `""` (when empty, will use the default as described above)

```ts
const config: HSConfig = {
    // ...
    px_custom_first_party_prefix: "/v1/12345678",
    // ...
}
```

### px\_custom\_first\_party\_sensor\_endpoint

For an application with ID `PX12345678`, the first party sensor endpoint is `/12345678/init.js` by default. This configuration customizes the entire first party sensor script endpoint. Note that in addition to responding to requests that match this configured route, the enforcer will also proxy first party requests that match the default pattern (`/12345678/init.js`) and patterns according to the custom prefix (`/<px_custom_first_party_prefix>/init.js`) if one is configured.

**Default**: `""`

```ts
const config: HSConfig = {
    // ...
    px_custom_first_party_sensor_endpoint: "/human_sensor",
    // ...
}
```

### px\_custom\_first\_party\_xhr\_endpoint

For an application with ID `PX12345678`, the first party XHR endpoint is `/12345678/xhr` by default. This configuration customizes the first party XHR endpoint. Note that in addition to responding to requests that match this configured route, the enforcer will also proxy first party requests that match the default pattern (`/12345678/xhr/*`) and patterns according to the custom prefix (`/<px_custom_first_party_prefix>/xhr/*`) if one is configured.

**Default**: `""`

```ts
const config: HSConfig = {
    // ...
    px_custom_first_party_xhr_endpoint: "/human_xhr",
    // ...
}
```

### px\_custom\_first\_party\_captcha\_endpoint

For an application with ID `PX12345678`, the first party captcha endpoint is `/12345678/captcha` by default. This configuration customizes the first party captcha endpoint. Note that in addition to responding to requests that match this configured route, the enforcer will also proxy first party requests that match the default pattern (`/12345678/captcha/*`) and patterns according to the custom prefix (`/<px_custom_first_party_prefix>/captcha/*`) if one is configured.

**Default**: `""`

```ts
const config: HSConfig = {
    // ...
    px_custom_first_party_captcha_endpoint: "/human_captcha",
    // ...
}
```

### px\_first\_party\_timeout\_ms

The maximum time in milliseconds to wait for first party requests.

**Default**: `4000`

```ts
const config: HSConfig = {
    // ...
    px_first_party_timeout_ms: 5000,
    // ...
}
```

### px\_bypass\_monitor\_header

When enabling the enforcer for the first time, it is recommended to do so in monitor mode to collect data before actually starting to block user requests. Prior to switching the module mode to active\_blocking entirely, it's also crucial to verify that the full blocking flow works as expected. This feature activates the full blocking flow even while in monitor mode if a particular header is present on the request.

**Default**: `""`

```ts
const config: HSConfig = {
    // ...
    px_bypass_monitor_header: 'x-px-block',
    // ...
}
```

### px\_enforced\_routes

Customers may want certain, but not all, endpoints to be enforced by HUMAN, even when the Enforcer is in monitor mode. These routes will go through the full enforcer workflow, including blocking requests when necessary. That is, even when the enforcer is in monitor mode, these defined routes will behave as if in active blocking mode.

**Default**: `[]`

```ts
const config: HSConfig = {
    // ...
    px_enforced_routes: ['/enforced_route', /.*\/enforced\/regex$/],
    // ...
}
```

### px\_monitored\_routes

Enables certain endpoints to be monitored rather than enforced by HUMAN, even when the enforcer is in active blocking mode.

**Default**: `[]`

```ts
const config: HSConfig = {
    // ...
    px_monitored_routes: ['/monitored_route', /.*\/monitored\/regex$/],
    // ...
}
```

### px\_sensitive\_headers

The HUMAN detector requires information about the HTTP request as part of its bot detections. Certain headers may contain information that should not be forwarded to other servers, including the HUMAN backend. Configuring these header names as sensitive headers will remove these headers from requests sent to other backends by HUMAN.

**Default**: `["cookie", "cookies"]`

```ts
const config: HSConfig = {
    // ...
    px_sensitive_headers: ['x-sensitive-token'],
    // ...
}
```

### px\_sensitive\_routes

Certain endpoints may require more stringent protection from bot attacks (e.g., endpoints that execute payments or handle personal information). In these cases, routes can be configured as sensitive routes, meaning risk API calls will be made even if the request contains a valid, unexpired cookie.

**Default**: `[]`

```ts
const config: HSConfig = {
    // ...
    px_sensitive_routes: ['/login', /.*\/sensitive\/regex$/],
    // ...
}
```

### px\_filter\_by\_extension

HUMAN does not enforce static assets such as images and documents. To prevent unnecessary API calls to HUMAN servers and needless computation, the enforcer filters all requests with a valid static file extension. Filtering by extension only applies to HTTP requests with methods GET and HEAD.

**Default**: `[ '.css', '.bmp', '.tif', '.ttf', '.docx', '.woff2', '.js', '.pict', '.tiff', '.eot', '.xlsx', '.jpg', '.csv', '.eps', '.woff', '.xls', '.jpeg', '.doc', '.ejs', '.otf', '.pptx', '.gif', '.pdf', '.swf', '.svg', '.ps', '.ico', '.pls', '.midi', '.svgz', '.class', '.png', '.ppt', '.mid', '.webp', '.jar', '.json', '.xml' ]`

```ts
const config: HSConfig = {
    // ...
    px_filter_by_extension: ['.css', '.js', '.png'],
    // ...
}
```

### px\_filter\_by\_http\_method

Filters out requests according to their HTTP method, avoiding unnecessary traffic in the enforcer verification flow and reducing operating costs.

**Default**: `[]`

```ts
const config: HSConfig = {
    // ...
    px_filter_by_http_method: ['OPTIONS'],
    // ...
}
```

### px\_filter\_by\_ip

Filters out requests according to their IP address, avoiding unnecessary traffic in the enforcer verification flow and reducing operation costs.

**Default**: `[]`

```ts
const config: HSConfig = {
    // ...
    px_filter_by_ip: ['1.1.1.1', '2.2.2.2/8'],
    // ...
}
```

### px\_filter\_by\_route

Route prefixes (endpoints) specified here will not be blocked, regardless of the score they receive. A request to a filtered route will not generate any risk or async activities.

**Default**: `[]`

```ts
const config: HSConfig = {
    // ...
    px_filter_by_route: ['/filtered_route', /.*\/filtered\/regex$/],
    // ...
}
```

### px\_filter\_by\_user\_agent

Filters out requests according to their user agent value, avoiding unnecessary traffic in the enforcer verification flow and reducing operation costs.

**Default**: `[]`

```ts
const config: HSConfig = {
    // ...
    px_filter_by_user_agent: ['filtered_UA'],
    // ...
}
```

### px\_css\_ref

Provides a way to include an additional custom .css file to add to the block page.

**Default**: `""`

```ts
const config: HSConfig = {
    // ...
    px_css_ref: 'https://www.example.com/custom_style.css',
    // ...
}
```

### px\_js\_ref

Provides a way to include a custom JS script to add to the block page. This script will run after the default JS scripts.

**Default**: `""`

```ts
const config: HSConfig = {
    // ...
    px_js_ref: 'https://www.example.com/custom_script.js',
    // ...
}
```

### px\_custom\_logo

Adds a custom logo to the block page that will be shown to users. This aligns the block page with the customer's brand.

**Default**: `""`

```ts
const config: HSConfig = {
    // ...
    px_custom_logo: 'https://www.example.com/custom_logo.png',
    // ...
}
```

### px\_custom\_cookie\_header

The Enforcer attempts to extract the HUMAN cookies from the 'Cookie' header. If the HUMAN cookies are transferred on a header other than 'Cookies', the header name should be configured here.

**Default**: `"x-px-cookies"`

```ts
const config: HSConfig = {
    // ...
    px_custom_cookie_header: 'x-custom-cookies',
    // ...
}
```

### px\_user\_agent\_max\_length

The maximum length of the `User-Agent` header. If the user agent header value exceeds this length, it will be truncated to this length prior to processing.

**Default**: `8528`

```ts
const config: HSConfig = {
    // ...
    px_user_agent_max_length: 2048,
    // ...
}
```

> **Note**
>
> This value should not be changed without consulting with the HUMAN Customer Success team.

### px\_additional\_activity\_handler

The additional activity handler is a custom function passed to the enforcer. The enforcer runs this callback after sending `page_requested` or `block` activity to the collector, and before forwarding the request to the next step in the pipeline. A common use case of the additional activity handler is to set the score as a variable or header. Then the application can read the score and do what is defined within the application's logic.

* Parameters
  * config: HSConfig
  * context: IContext
  * event: [APIGatewayRequestAuthorizerEvent](https://docs.aws.amazon.com/apigateway/latest/developerguide/api-gateway-lambda-authorizer-input.html#w38aac15b9c11c26c29b5)
* Returns `void | Promise<void>`

**Default**: `null`

```ts
const config: HSConfig = {
    // ...
    px_additional_activity_handler: (
        config: HSConfig,
        context: IContext,
        event: APIGatewayRequestAuthorizerEvent
    ): void => {
        event.headers['X-Human-Score'] = `${context.score}`;
        event.headers['X-Human-Rtt'] = `${context.riskApiData.riskRtt}`;
    },
    // ...
}
```

### px\_enrich\_custom\_parameters

This custom function enriches activities sent from the enforcer to HUMAN with additional custom data. This data can include user information, session IDs, or other data that HUMAN should have access to. These custom parameters are defined by a configurable function that must return an object that contains these custom parameters. There is a limit of 10 custom parameters.

* Parameters
  * config: HSConfig
  * event: [APIGatewayRequestAuthorizerEvent](https://docs.aws.amazon.com/apigateway/latest/developerguide/api-gateway-lambda-authorizer-input.html#w38aac15b9c11c26c29b5)
* Returns `CustomParameters` | `Promise<`CustomParameters`>`

**Default**: null

```ts
const config: HSConfig = {
    // ...
    px_enrich_custom_parameters: async (
        config: HSConfig,
        event: APIGatewayRequestAuthorizerEvent,
    ): `CustomParameters` | `Promise<`CustomParameters`>` => {
        return {
            custom_param1: 'hardcoded value',
            custom_param2: event.headers['Header-Name'],
        };
    },
    // ...
}
```

### px\_logger\_auth\_token

The token used to authenticate with HUMAN's enforcer logging services. This value is required for setting up the header-based logger feature.

**Default**: `""`

```ts
const config: HSConfig = {
    // ...
    px_logger_auth_token: '<LOGGER_AUTH_TOKEN>',
    // ...
}
```

## Account Defender Configurations

### px\_jwt\_cookie\_name

The name of the cookie that contains the JWT token from which user identifiers should be extracted.

**Default**: `""`

```ts
const config: HSConfig = {
    // ...
    px_jwt_cookie_name: 'auth',
    // ...
}
```

### px\_jwt\_cookie\_user\_id\_field\_name

The field name in the JWT object, extracted from the JWT cookie, that contains the user ID to be extracted and reported.

**Default**: `""`

```ts
const config: HSConfig = {
    // ...
    px_jwt_cookie_user_id_field_name: 'nameID',
    // ...
}
```

### px\_jwt\_cookie\_additional\_field\_names

The field names in the JWT object, extracted from the JWT cookie, that should be extracted and reported in addition to the user ID.

**Default**: `[]`

```ts
const config: HSConfig = {
    // ...
    px_jwt_cookie_additional_field_names: ['exp', 'iss'],
    // ...
}
```

### px\_jwt\_header\_name

The name of the header that contains the JWT token from which user identifiers should be extracted.

**Default**: `""`

```ts
const config: HSConfig = {
    // ...
    px_jwt_header_name: 'x-jwt-authorization',
    // ...
}
```

### px\_jwt\_header\_user\_id\_field\_name

The field name in the JWT object, extracted from the JWT header, that contains the user ID to be extracted and reported.

**Default**: `""`

```ts
const config: HSConfig = {
    // ...
    px_jwt_header_user_id_field_name: 'sub',
    // ...
}
```

### px\_jwt\_header\_additional\_field\_names

The field names in the JWT object, extracted from the JWT header, that should be extracted and reported in addition to the user ID.

**Default**: `[]`

```ts
const config: HSConfig = {
    // ...
    px_jwt_header_additional_field_names: ['exp', 'iss'],
    // ...
}
```

## Credential Intelligence Configurations

> **Important**
>
> Credential Intelligence necessitates delivery of the credentials on the incoming HTTP request to HUMAN's detection servers. It also requires an indication whether the request resulted in a successful login or not.
>
> Since most credentials are sent in HTTP request bodies, and since [AWS API Gateway does not provide the HTTP request body in the input event to Lambda Authorizers](https://docs.aws.amazon.com/apigateway/latest/developerguide/api-gateway-lambda-authorizer-input.html#w38aac15b9c11c26c29b5), **the enforcer can extract only credentials that are present on the HTTP request headers or query parameters**. Credentials on the HTTP request body *cannot* be extracted.
>
> Additionally, since the Lambda Authorizers operate only on the incoming HTTP request and not on the HTTP response returned to the end user, the login successful indication cannot be automatically reported to HUMAN. This must be done by setting `px_automatic_additional_s2s_activity_enabled` to `false` and setting `px_additional_s2s_activity_header_enabled` to `true`. For more details on providing login success information, see the descriptions for these configuration.
>
> For more information on setting up Credential Intelligence for this Enforcer, please reach out to the HUMAN Customer Success Team.

### px\_login\_credentials\_extraction\_enabled

This enables the extraction and reporting of credentials from the Enforcer. This must be set to `true` to enable the Credential Intelligence product.

**Default**: `false`

```ts
const config: HSConfig = {
    // ...
    px_login_credentials_extraction_enabled: true,
    // ...
}
```

### px\_login\_credentials\_extraction

An array of configurations for each credential endpoint. Each element in the array is an object representing a distinct endpoint to which credentials are sent, and includes information about how to identify these credential-bearing requests and how to extract the credentials from the request.

**Default**: `[]`

```ts
const config: HSConfig = {
    // ...
    px_login_credentials_extraction: [
        {
            path: '/auth/[A-Za-z0-9]{12}/login',
            path_type: 'regex',
            method: 'GET',
            sent_through: 'query-param',
            user_field: 'username',
            pass_field: 'password',
        },
        {
            path: '/sign-up',
            method: 'POST',
            sent_through: 'custom',
            extract_credentials_callback: (event: APIGatewayRequestAuthorizerEvent): Credentials => {
                if (event.headers['X-Reject-Signup'] === '1') {
                    return null;
                }
                return {
                    user: event.headers['X-Username-Header'],
                    pass: event.queryStringParameters.password
                };
            },
        },
        // ...
    ],
    // ...
}
```

Each credential endpoint configuration object contains the following fields:

#### path

**Required**. The path of the request that contains the credentials. It can be either an exact path or a string in the form of a regular expression.

```ts
{
    // ...
    path: '/sign-up',
    // ...
}
```

#### path\_type

**Optional**. Whether the incoming request path should be evaluated against the configured path as a regular expression or as an exact match.

Possible values:

* `"exact"` - The value set in `path` must match the request path exactly as is.
* `"regex"` - The value set in `path` represents a regular expression to be matched against the request path.

**Default**: `"exact"`

```ts
{
    // ...
    path: '/auth/[A-Za-z0-9]{12}/login',
    path_type: 'regex',
    // ...
}
```

#### method

**Required**. The HTTP method of the request that contains the credentials. This can be set to any string representing an HTTP method (e.g., `"GET"`, `"POST"`, `"PUT"`).

```ts
{
    // ...
    method: 'POST',
    // ...
}
```

#### sent\_through

**Required**. Whether the credentials should be extracted from the request headers, query parameters, or via a defined custom callback.

Possible values:

* `"header"` - The credentials will be extracted from the request headers according to the configured `user_field` and `pass_field`.
* `"query-param"` - The credentials will be extracted from the query parameters according to the configured `user_field` and `pass_field`.
* `"custom"` - The credentials will be extracted by invoking the `extract_credentials_callback`.

> **Note**
>
> API Gateway Lambda Authorizers do not have access to the HTTP request body. Therefore, it is not possible to set "sent\_through" to the value "body".

#### user\_field

**Required** only if `sent_through` is set to, `"header"` or `"query-param"`.

The name of the field, header name, or query parameter where the username can be found.

```ts
{
    // ...
    sent_through: 'header',
    user_field: 'X-Username-Header',
    // ...
}
```

#### pass\_field

**Required** only if `sent_through` is set to `"header"` or `"query-param"`.

The name of the field, header name, or query parameter where the password can be found.

```ts
{
    // ...
    sent_through: 'query-param',
    pass_field: 'password',
    // ...
}
```

#### extract\_credentials\_callback

**Required** only if `sent_through` is set to `"custom"`.

A custom credential extraction callback that returns the raw credentials from the request. It receives the HTTP request as a parameter and should return a Credentials object of the following type.

```ts
type Credentials = {
    user?: string;  // the raw username
    pass?: string;  // the raw password
};
```

* Parameters
  * event: [APIGatewayRequestAuthorizerEvent](https://docs.aws.amazon.com/apigateway/latest/developerguide/api-gateway-lambda-authorizer-input.html#w38aac15b9c11c26c29b5)
* Returns Credentials or a Promise resolving to a Credentials object.

If neither the username nor the password can be extracted from the request, the function should return `null`.

```ts
{
    // ...
    sent_through: 'custom',
    extract_credentials_callback: async (event: APIGatewayRequestAuthorizerEvent): Promise<Credentials> => {
        // ...
        // custom extraction resulting in username and password
        // ...
        if (!username || !password) {
            // unsuccessful extraction
            return null;
        }
        // successfully extracted credentials
        return { user: username, pass: password };
    },
    // ...
}
```

#### protocol

**Optional**. Whether to process credentials as part of single or multiple HTTP requests. By default, the module tries to process requests depending on which credential fields were extracted.

Possible values:

* `"v2"` - Both username and password are present on the same HTTP request and must be extracted successfully to trigger Credential Intelligence.
* `"multistep_sso"` - The username and password are delivered on different HTTP requests. Either the username or password, but not both, must be extracted successfully to trigger Credential Intelligence.
* `"both"` - The username and password may be present on the same HTTP request or on different HTTP requests. If either username or password is successfully extracted, the Enforcer will send the credentials according to the `multistep_sso` protocol. If both username and password are successfully extracted, the Enforcer will send the credentials according to the `v2` protocol.

**Default**: `"both"`

```ts
{
    // ...
    protocol: 'v2',
    // ...
}
```

### px\_compromised\_credentials\_header

The header name to be set on the incoming request if the credentials are compromised. If this header is added, its value will always be `1`. If credentials have not been identified as compromised, the header will not be added to the request.

**Default**: `"px-compromised-credentials"`

```ts
const config: HSConfig = {
    // ...
    px_compromised_credentials_header: 'x-ci-compromised',
    // ...
}
```

### px\_send\_raw\_username\_on\_additional\_s2s\_activity

Whether to report the raw username on the `additional_s2s` activity. When set to `false`, the raw username will never be reported. When set to `true`, the raw username will only be reported if (1) the credentials are compromised, and (2) the login request was successful.

**Default**: `false`

```ts
const config: HSConfig = {
    // ...
    px_send_raw_username_on_additional_s2s_activity: true,
    // ...
}
```

### px\_automatic\_additional\_s2s\_activity\_enabled

Whether to send the `additional_s2s` activity, which reports on whether the login was successful, automatically in the `postEnforce` function. This should only be set to `false` if it is not possible to determine whether the login was successful based on the HTTP response. This means the `additional_s2s` activity must be sent in some other way.

**Default**: `true`

```ts
const config: HSConfig = {
    // ...
    px_automatic_additional_s2s_activity_enabled: false,
    // ...
}
```

### px\_additional\_s2s\_activity\_header\_enabled

Whether to attach the `additional_s2s` payload and URL as headers to the original request. This is done so that the `additional_s2s` activity can be enriched with the proper `login_successful` value and sent to the provided URL at a later stage. This should only be enabled if the `px_automatic_additional_s2s_activity_enabled` is set to `false`.

When set to `true`, the following headers are added to the origin request:

* `px-additional-activity` - A JSON object containing the payload of the `additional_s2s` activity. The `login_successful` and `http_status_code` fields should be set prior to sending the activity.
* `px-additional-activity-url` - The URL to which the `additional_s2s` payload should be sent as an HTTP POST request.

**Default**: `false`

```ts
const config: HSConfig = {
    // ...
    px_additional_s2s_activity_header_enabled: true,
    // ...
}
```

Below is an example of JavaScript code at the origin server to handle parsing, enrichment, and sending of the `additional_s2s` activities that arrive on request headers.

```js
app.post('/login', (req, res) => {
    // handle login flow, resulting in the variables:
    // isLoginSuccessful (boolean) and responseStatusCode (number)

    if (
        req.headers['px-additional-activity'] &&
        req.headers['px-additional-activity-url']
    ) {
        handlePxAdditionalActivity(req, responseStatusCode, isLoginSuccessful);
    }
});

function handlePxAdditionalActivity(req, statusCode, isLoginSuccessful) {
    try {
        // extract url and activity from the request headers
        const url = req.headers['px-additional-activity-url'];
        const activity = JSON.parse(req.headers['px-additional-activity']);

        // enrich the activity details with added information
        activity.details['http_status_code'] = statusCode;
        activity.details['login_successful'] = isLoginSuccessful;

        if (activity.details['credentials_compromised'] && isLoginSuccessful) {
            // add raw username if credentials are compromised and login is successful (only if desired)
            activity.details['raw_username'] = req.body.username;
        } else {
            // remove raw username if login is not successful or credentials are not compromised
            delete activity.details['raw_username'];
        }

        // send the POST request
        axios.post(url, activity, {
            headers: {
                'Authorization': `Bearer ${env.PX_AUTH_TOKEN}`,
                'Content-Type': 'application/json'
            }
        });
    } catch (err) {
        console.error(`Error: ${err}`);
    }
}
```

## Hype Sale Challenge

The enforcer will serve a Hype Sale Challenge for any request that is marked as a hype sale. To mark a request as hype sale, add a custom parameter with the key `is_hype_sale` and a boolean value of `true` in the configurable custom parameters function.

The following configuration will initiate a Hype Sale Challenge for any request that contains the query param `id` with the value `123` (e.g., `https://www.example.com/v1/product?id=123`).

```ts
const config: HSConfig = {
    // ...
    px_enrich_custom_parameters: async (
        config: HSConfig,
        event: APIGatewayRequestAuthorizerEvent,
    ): `CustomParameters` | `Promise<`CustomParameters`>` => {
        return {
            is_hype_sale: event.query['id'] === '123'
        };
    },
    // ...
}
```